如何将装饰器附加到函数;事后诸葛亮;用python?
我理解python中函数的装饰器(我可能错了)的方式是,它们应该添加副作用并修改函数的返回值。现在,在要装饰的函数的函数定义上方或通过赋值添加装饰器。下面是一个小例子:如何将装饰器附加到函数;事后诸葛亮;用python?,python,python-2.7,decorator,python-decorators,Python,Python 2.7,Decorator,Python Decorators,我理解python中函数的装饰器(我可能错了)的方式是,它们应该添加副作用并修改函数的返回值。现在,在要装饰的函数的函数定义上方或通过赋值添加装饰器。下面是一个小例子: def打印参数装饰(功能): def包装(*args,**kwargs): 打印“参数:”,args,kwargs#添加了副作用 返回函数(*args,**kwargs)*5#修改后的返回值 返回包装器 @印花装饰 def do_材料(strg,n=10): “”“重复strg几次。”“” 返回字符串*n new_decorde
def打印参数装饰(功能):
def包装(*args,**kwargs):
打印“参数:”,args,kwargs#添加了副作用
返回函数(*args,**kwargs)*5#修改后的返回值
返回包装器
@印花装饰
def do_材料(strg,n=10):
“”“重复strg几次。”“”
返回字符串*n
new_decorded_func=打印装饰(做东西)#分配装饰
打印待办事项('a',2)#输出:AAAAA
现在,如何将修饰符附加到别处定义的函数,理想情况下,保留原始函数的名称和docstring(如functools.wrapps
does)?例如,我正在从Python的数学模块中导入sqrt()
函数,并希望对其进行修饰,我该怎么做
从functools导入包装
从数学导入sqrt
def打印参数装饰(功能):
@包装(功能)
def包装(*args,**kwargs):
打印“参数:”,args,kwargs#添加了副作用
返回函数(*args,**kwargs)*5#修改后的返回值
返回包装器
#以某种方式装饰数学模块中的sqrt()函数
@印刷装饰???
sqrt#???
打印sqrt(9)
#输出:
#参数:([9],){}
#15#您将sqrt
导入到模块中,只需在您自己的全局名称空间中应用装饰器即可:
sqrt = print_args_decor(sqrt)
这将模块名称空间中的名称sqrt
设置为装饰器的结果。本模块中没有最初定义sqrt
的要求
由装饰器使用functools.wrapps()
decorator来保留函数元数据,如名称和docstring
装饰类在这方面没有什么不同:
ClassName = decorator(ClassName)
在Python2上,对于方法,您需要小心地获取原始的未绑定函数;最简单的方法是使用方法。\uuuu func\uuu
属性:
try:
# Python 2
ClassName.function_name = decorator(ClassName.function_name.__func__)
except AttributeError:
# Python 3
ClassName.function_name = decorator(ClassName.function_name)
我已将上述内容包装在一个try…中,但
除外,以使模式在Python版本中工作。另一种方法是从类\uuuu dict\uuu
中获取函数对象,以避免描述符协议进入:
ClassName.function_name = decorator(ClassName.__dict__['function_name'])
看起来很简单,谢谢。你能添加一个在类中修饰类和方法的例子吗?@con-f-use:decorator只是一个可调用的函数。正如您所说的那样,@decorator
语法只是将修饰对象传递给decorator callable,并用结果替换名称。因此,对于一个仅仅是ClassName=decorator(ClassName)
@con-f-use的类来说:现有的方法有点棘手,因为decorator在函数对象成为类的一部分之前就应用于函数对象。您可以使用\uuuu func\uuu
属性获取原始函数:ClassName.function\u name=decorator(ClassName.function\u name.\uuu func\uu)
。