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

相关推荐

  • phpstudy配置虚拟主机

    想必大家对于phpstudy这个工具都不陌生,它是一款非常实用的PHP环境配置工具,为众多的网站开发者提供了便利。而今天我们要介绍的是phpstudy在虚拟主机方面的应用,相信大家…

    行业资讯 2024年3月20日
    0
  • 茂名关键词优化报价,茂名关键词排名提升

    您对SEO行业感兴趣吗?您想知道如何通过关键词优化来提高网站排名和流量吗?接下来我们就来看看茂名市SEO关键词优化的步骤和技巧,以及成功案例分析。在这篇文章中,我们将解释什么是SE…

    行业资讯 2024年4月3日
    0
  • cdn被ddos算是流量么,cdn 违法

    3.网络攻击技术变得越来越复杂 随着网络攻击技术的不断发展,黑客一直在寻找新的攻击方法来渗透网站的防御。例如,CDN 网站很容易通过DDoS 攻击、SQL 注入、XSS 跨站脚本等…

    行业资讯 2024年5月10日
    0
  • 团购网站设计,团购网站制作

    团购网站模板提供多种模板选项,根据不同行业和需求,不同风格和功能可供选择。这些模板经过精心设计,具有独特的外观和布局,可以吸引您的注意力并增强您的用户体验。 2.简单易用的后台管理…

    行业资讯 2024年4月18日
    0

发表回复

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