本系列文档:1.终于弄明白了Python的装饰器(一)2.终于弄明白了Python的装饰器(二)3.终于弄懂了Python的装饰器(三)4.终于明白了Python的装饰器(四)4.装饰器参数的用法,你可以把它应用到任何函数或方法),然后就用*args,**kwargs:defa_decorator_passing_arbitrary_arguments(function_to_decorate):#Thewrapperacceptsanyparameters(这部分可以参考文档:+++++++SupplementaryDocumentation++++++++++++++)defa_wrapper_accepting_arbitrary_arguments(*args,**kwargs):print("DoIhaveargs?:")print(args)print(kwargs)function_to_decorate(*args,**kwargs)returna_wrapper_accepting_arbitrary_arguments@a_decorator_passing_arbitrary_argumentsdeffunction_with_no_argument():print("Python很酷,这里没有参数。")function_with_no_argument(?)#Python很酷,这里没有参数。@a_decorator_passing_arbitrary_argumentsdeffunction_with_arguments(a,b,c):print(a,b,c)function_with_arguments(1,2,3)#输出:#DoIhaveargs?:#(1,2,3)#{}#123@a_decorator_passing_arbitrary_argumentsdeffunction_with_named_arguments(a,b,c,platypus="为什么不呢?"):print("{0},{1}和{2}喜欢鸭嘴兽吗?{3}".format(a,b,c,platypus))function_with_named_arguments("Bill","Linus","Steve",platypus="Indeed!")#Output:#DoIhaveargs吗?:#('Bill','Linus','Steve')#{'platypus':'Indeed!'}#Bill、Linus和Steve喜欢鸭嘴兽吗?Indeed!classMary(object):def__init__(self):self.age=31@a_decorator_passing_arbitrary_argumentsdefsayYourAge(self,lie=-3):#你现在可以添加一个默认值print("Iam{0},what你觉得吗?".format(self.age+lie))m=Mary()m.sayYourAge()#Output:#DoIhaveargs?:#(<__main__.Maryobjectat0xb7d303ac>,)#{}#我28岁,你怎么看?最佳实践:装饰器注意:装饰器是在Python2.4中引入的,因此请确保您的代码将在>=2.4上运行,其中装饰器会使函数调用变慢。(记住这一点)你不能取消装饰这个功能。(有一些技巧可以创建可以移除的装饰器,但没有人使用它们。)所以一旦你装饰了一个函数,你就装饰了你所有的代码。装饰器包装函数,这会使它们更难调试。(这针对Python>=2.5进行了调整;见下文。)functools模块是在Python2.5中引入的。它包括函数functools.wraps(),它将装饰函数的名称、模块和文档字符串复制到它的包装器中。(有趣的事实:functools.wraps()也是一个装饰器!)#对于调试,堆栈跟踪将向您显示函数__name__deffoo():print("foo")print(foo.__name__)#Output:foo#Whendecorators被使用了,输出信息会变得乱七八糟,不再是foo,而是wrapperdefbar(func):defwrapper():print("bar")returnfunc()returnwrapper@bardeffoo():print("foo")print(foo.__name__)#Output:wrapper#"functools"canhelpforthatimportfunctoolsdefbar(func):#我们说"wrapper",正在包装"func"#魔法开始了@functools.wraps(func)defwrapper():print("bar")returnfunc()returnwrapper@bardeffoo():print("foo")print(foo.__name__)#outputs:fooPython本身提供了一些装饰:property,staticmethod等Django使用装饰器来管理缓存和查看权限。假内联异步函数调用。如何使用链式装饰器?#大胆使用链式装饰器defmakebold(fn):#装饰器返回的新函数defwrapper():#前后插入一些代码return""+fn()+""returnwrapper#Thedecoratortomakeititalicdefmakeitalic(fn):#装饰器返回的新函数defwrapper():#在return""+fn()+""前后插入一些代码returnwrapper@makebold@makeitalicdefsay():return"hello"print(say())#Output:hello#这与defsay()完全等价:return"hello"say=makebold(makeitalic(say))print(say())#Output:hello现在,你可以暂时放下开心的心情,让我们使用我们的大脑并看到装饰器的高级用法。
