Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将装饰器附加到函数;事后诸葛亮;用python?_Python_Python 2.7_Decorator_Python Decorators - Fatal编程技术网

如何将装饰器附加到函数;事后诸葛亮;用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

我理解python中函数的装饰器(我可能错了)的方式是,它们应该添加副作用并修改函数的返回值。现在,在要装饰的函数的函数定义上方或通过赋值添加装饰器。下面是一个小例子:

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)