use*_*743 2 python attributes function decorator
我是Python的新手,我不明白函数本身看起来有什么属性.在下面的代码中,有一个名为f的函数,稍后在代码中引用了名为f.count的函数.一个函数,即f,如何有一个.count?我收到一条错误消息:'NoneType'对象在该行上没有属性'count',所以它显然还没有该属性.我该如何赋予它属性?
def fcount(n):
print n.__name__
@fcount
def f(n):
return n+2
for n in range(5):
print n
#print f(n)
print 'f count =',f.count #THE LINE CAUSING THE ERROR MENTIONED ABOVE
@fcount
def g(n):
return n*n
print 'g count =',g.count
print g(3)
print 'g count =',g.count
Run Code Online (Sandbox Code Playgroud)
编辑:添加了fcount(),它没有做任何事情,还有关于错误的详细信息.
让我们从定义开始f:
@fcount
def f(n):
return n+2
Run Code Online (Sandbox Code Playgroud)
这将a定义f为函数调用的返回值,该函数在此处fcount用作装饰器(前导@).
此代码大致相当于
def f(n):
return n+2
f = fcount(f)
Run Code Online (Sandbox Code Playgroud)
由于装饰- fcount-不返回任何东西,f是None 和不是一个函数在调用点.
在你的情况下fcount应该返回一些函数并count为返回的函数添加一个属性.有用的东西(?)可能是
def fcount(fn):
def wrapper(n):
wrapper.count += 1
return fn(n)
wrapper.count = 0
return wrapper
Run Code Online (Sandbox Code Playgroud)
编辑
正如@jonrsharpe指出的那样,通用装饰器可以通过在签名中捕获它们来转发位置和关键字参数,*args并**kwargs在调用另一个函数时以相同的方式扩展它们.名称args和kwargs惯例使用.
Python还有一个辅助函数(一个装饰器本身),可以将信息(名称,文档字符串和签名信息)从一个函数传递到另一个函数:functools.wraps.一个完整的示例如下所示:
from functools import wraps
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@decorator
def f(a, b, c=None):
"The useful f function"
pass
print f.__name__ # `f` rather than `wrapper`
print help(f) # `f(*args, **kwargs) The useful f function` rather than `wrapper(*args, **kwargs)`
Run Code Online (Sandbox Code Playgroud)