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

相关推荐

  • steam被墙了怎么解决,假如steam被墙

    Steam被阻塞是令游戏玩家头疼的问题。不过,也不必灰心。您可以使用VPN等方法解决此问题。同时提醒大家,在享受游戏的同时,也要注意网络安全。如果您需要CDN加速和网络安全服务,请…

    行业资讯 2024年5月10日
    0
  • vsping测评:哪家云服务器的高防性能更强?

    云服务器行业备受关注,而高防性能更是备受瞩目。近年来,随着网络攻击手段的不断升级,高防云服务器的重要性也日益凸显。那么,什么是高防云服务器?它又有哪些技术特点?为了给读者带来更全面…

    行业资讯 2024年4月16日
    0
  • 如何有效地购买外链?

    想要让自己的网站在搜索引擎中获得更好的排名,除了优化网站内容和结构外,外链也是不可忽视的重要因素。但是如何有效地购买外链却是许多网站管理员头疼的问题。今天我们就来聊一聊如何选择合适…

    行业资讯 2024年4月13日
    0
  • js面试题003

    What is the Event Loop? Is it part of V8? 什么是事件循环? The event loop is a fundamental concept…

    行业资讯 2024年5月31日
    0

发表回复

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