python函数工具——“三大器”

今天学习装饰器。
装饰器是一个高阶函数,它接受一个函数作为输入并返回一个新的函数,通常用于在不改变原函数代码情况下,增强或修改函数行为。装饰器提供了一种优雅的方法来添加功能或进行函数包装,是python中常用的设计模式。
下面看一个实例便于理解。
def my_decorator(func):def wrapper():        print("Something is happening before the function is called")        func()        print("Something is happening after the function is called")return wrapper@my_decoratordef say_hello():    print("Hello!")say_hello()

outSomething is happening before the function is calledHello!Something is happening after the function is called

多看几遍以上的代码,还有下面的输出结果。假如没有@my_decorator语法糖(syntactic sugar,是指一些简洁和方便的语法结构,它们使代码更易读和编写,但并不会添加新的功能或改变语言的基本行为。),结果是这样:

Hello!
所以我们可以这样理解,有装饰器的存在,改变了say_hello()函数的行为:
@my_decoratordef say_hello():    ...
等价于
def say_hello():...say_hello = my_decorator(say_hello)
使用带参数的装饰器
装饰器不仅可以装饰无参数的函数,也可以装饰有参数的函数。为了实现这一点,需要确保包装函数‘wrapper’能接受任意数量的位置参数和关键词参数。

上面划线部分需要复习之前函数部分,*args是代表可变的位置参数,**kwargs是带边可变的关键词参数

def my_decorator(func):    def wrapper(*args, **kwargs):        print("Before function call")        result = func(*args, **kwargs)        print("After function call")        return result    return wrapper

@my_decoratordef greet(name):    print(f"Hello,{name}!")

greet("Alice")

outBefore function callHello,Alice!After function call

 

装饰器与返回值
装饰器函数可以返回原始函数的返回值,这样包装函数的行为与原始函数一致。
def my_decorator(func):    def wrapper(*args, **kwargs):        print("Before function call")        result = func(*args, **kwargs)        print("After function call")        return result    return wrapper
@my_decoratordef add(a, b):    return a + b
result = add(3, 4)print(f"Result: {result}")
outBefore function callAfter function callResult:11
应用多个装饰器
可以将多个装饰器应用到一个函数,装饰器由内向外依次应用。
def decorator1(func):    def wrapper(*args, **kwargs):        print("Decorator 1 before")        result = func(*args, **kwargs)        print("Decorator 1 after")        return result    return wrapper
def decorator2(func):    def wrapper(*args, **kwargs):        print("Decorator 2 before")        result = func(*args, **kwargs)        print("Decorator 2 after")        return result    return wrapper
@decorator1@decorator2def say_hello():    print("Hello!")
say_hello()

outDecorator 1 beforeDecorator 2 beforeHello!Decorator 2 afterDecorator 1 after
 带参数的装饰器
装饰器本身也可以接受参数。这需要在嵌套一层函数,用于传递参数。
def repeat(num_times):    def decorator(func):        def wrapper(*args, **kwargs):            for _ in range(num_times):                result = func(*args, **kwargs)            return result        return wrapper    return decorator
@repeat(num_times=3)def say_hello():    print("Hello!")
say_hello()
out
Hello!Hello!Hello!
使用‘functools.wraps’保留原函数信息
使用装饰器时,原函数的元数据(如函数名、文档字符串等)可能会丢失。可以使用 functools.wraps 装饰包装函数,保留原函数的元数据。
import functools
def my_decorator(func):    @functools.wraps(func)    def wrapper(*args, **kwargs):        print("Before function call")        result = func(*args, **kwargs)        print("After function call")        return result    return wrapper
@my_decoratordef say_hello():    """This is a docstring for say_hello function."""    print("Hello!")
print(say_hello.__name__)  # 输出:say_helloprint(say_hello.__doc__)   # 输出:This is a docstring for say_hello function.

代码地带

一个简单的缓存装饰器,用于缓存函数的计算结果,避免重复计算。

import functools
def cache(func):    cached_results = {}    @functools.wraps(func)    def wrapper(*args):        if args in cached_results:            return cached_results[args]        result = func(*args)        cached_results[args] = result        return result    return wrapper
@cachedef compute_square(n):    return n * n
print(compute_square(4))  # 输出:16print(compute_square(4))  # 输出:16(使用缓存结果)

原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/89543.html

(0)
guozi's avatarguozi
上一篇 2024年6月4日 下午5:02
下一篇 2024年6月4日 下午5:03

相关推荐

  • 如何快速提升手机网站的seo排名?

    想要在手机网站上获得更多的流量和曝光率,SEO排名是一个不可忽视的因素。那么什么是SEO排名?为什么它对手机网站至关重要?如何优化手机网站的内容和结构以提升SEO排名?这些都是每个…

    行业资讯 2024年4月18日
    0
  • app应用开发多少钱,app开发需要多少费用

    如果你想开发一个应用程序,很多人可能会问重要的问题。 “需要多少钱?”事实上,这个问题并不容易回答,因为不同应用程序的开发成本有所不同。但是,如果您想了解应用程序开发所需的基础知识…

    行业资讯 2024年4月2日
    0
  • 网游服务器租用

    今天,我们要谈论的是一个备受关注的话题——网游服务器租用。随着网络游戏行业的蓬勃发展,越来越多的游戏企业开始意识到拥有一个稳定高效的网游服务器对于游戏运营的重要性。但是,什么是网游…

    行业资讯 2024年3月22日
    0
  • 大连企业建站

    大连企业建站,是一个越来越受到关注的话题。随着互联网技术的发展,越来越多的企业开始意识到建立自己的网站对于业务发展的重要性。然而,如何选择适合的云服务器服务商?云服务器又有哪些基本…

    行业资讯 2024年4月19日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注