时间:2021-05-22
问题
你想在函数上添加一个包装器,增加额外的操作处理(比如日志、计时等)。
解决方案
如果你想使用额外的代码包装一个函数,可以定义一个装饰器函数,例如:
import timefrom functools import wrapsdef timethis(func): ''' Decorator that reports the execution time. ''' @wraps(func) def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(func.__name__, end-start) return result return wrapper下面是使用装饰器的例子:
>>> @timethis... def countdown(n):... '''... Counts down... '''... while n > 0:... n -= 1...>>> countdown(100000)countdown 0.008917808532714844>>> countdown(10000000)countdown 0.87188299392912>>>讨论
一个装饰器就是一个函数,它接受一个函数作为参数并返回一个新的函数。当你像下面这样写:
@timethisdef countdown(n): pass跟像下面这样写其实效果是一样的:
def countdown(n): passcountdown = timethis(countdown)顺便说一下,内置的装饰器比如 @staticmethod, @classmethod,@property 原理也是一样的。例如,下面这两个代码片段是等价的:
class A: @classmethod def method(cls): passclass B: # Equivalent definition of a class method def method(cls): pass method = classmethod(method)在上面的 wrapper() 函数中,装饰器内部定义了一个使用 *args 和 **kwargs 来接受任意参数的函数。在这个函数里面调用了原始函数并将其结果返回,不过你还可以添加其他额外的代码(比如计时)。然后这个新的函数包装器被作为结果返回来代替原始函数。
需要强调的是装饰器并不会修改原始函数的参数签名以及返回值。使用 *args 和 **kwargs 目的就是确保任何参数都能适用。而返回结果值基本都是调用原始函数 func(*args, **kwargs) 的返回结果,其中func就是原始函数。
刚开始学习装饰器的时候,会使用一些简单的例子来说明,比如上面演示的这个。不过实际场景使用时,还是有一些细节问题要注意的。比如上面使用 @wraps(func) 注解是很重要的,它能保留原始函数的元数据(下一小节会讲到),新手经常会忽略这个细节。接下来的几个小节我们会更加深入的讲解装饰器函数的细节问题,如果你想构造你自己的装饰器函数,需要认真看一下。
以上就是Python 在函数上添加包装器的详细内容,更多关于Python 添加包装器的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
一个装饰器已经作用在一个函数上,你想撤销它,直接访问原始的未包装的那个函数。假设装饰器是通过@wraps来实现的,那么你可以通过访问wrapped属性来访问原始
问题一个装饰器已经作用在一个函数上,你想撤销它,直接访问原始的未包装的那个函数。解决方案假设装饰器是通过@wraps来实现的,那么你可以通过访问__wrappe
第一种方法,在视图函数上边添加一条语句@csrf_exempt例子:@csrf_exemptdeflogin(request):returnrender_to_
本文实例讲述了Python装饰器原理与用法。分享给大家供大家参考,具体如下:1、装饰器的本质是函数,主要用来装饰其他函数,也就是为其他函数添加附加功能2、装饰器
jQuery式的方法链核心部分是三点:1)jquery的包装器函数(也就是jQuery(),以此来构建包装器对象),以此构造函数可以产生饱含了原生DOM对象的包