具有函数属性的Python装饰器
我一直在尝试装饰,并发现一个有趣的不一致与他们,希望你可以帮助我解决它 首先,我有一个这样的装饰师:具有函数属性的Python装饰器,python,python-2.7,python-decorators,Python,Python 2.7,Python Decorators,我一直在尝试装饰,并发现一个有趣的不一致与他们,希望你可以帮助我解决它 首先,我有一个这样的装饰师: >>> def name(n): ... def decorator(fun): ... fun.name = n ... return fun ... return decorator 我是这样用的: >>> @name("my name jeff") ... def f(): ...
>>> def name(n):
... def decorator(fun):
... fun.name = n
... return fun
... return decorator
我是这样用的:
>>> @name("my name jeff")
... def f():
... print f.name
由于decorator带来了乐趣,我可以做两件事:
>>> f()
my name jeff
>>> f.name
'my name jeff'
这一切都很好,也正是我所期望的。现在有点奇怪了。我的新装饰师如下:
>>> def name(n):
... def decorator(fun):
... fun.name = n
... def wrapper():
... return fun()
... return wrapper
... return decorator
>>> def name(n):
... def decorator(fun):
... fun.name = n
... def wrapper():
... return fun()
... return wrapper
... return decorator
对我来说,它看起来应该做和之前一样的事情,但是我得到:
>>> @name("my name jeff")
... def f():
... print f.__name__
... print f.name
...
>>> f()
wrapper
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in wrapper
File "<stdin>", line 4, in f
AttributeError: 'function' object has no attribute 'name'
我不是什么python忍者,所以如果我遗漏了一些明显的东西,请指出。你的装饰师如下:
>>> def name(n):
... def decorator(fun):
... fun.name = n
... def wrapper():
... return fun()
... return wrapper
... return decorator
>>> def name(n):
... def decorator(fun):
... fun.name = n
... def wrapper():
... return fun()
... return wrapper
... return decorator
您正在为fun
设置name
属性,但返回的是wrapper
。
换句话说,您将fun
替换为wrapper
,它实际上没有name
属性
您可以尝试以下方法:
>>> def f():
... print f.__name__
... print f.name
...
>>> x = name("jeff")(f)
>>> x.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'name'
>>> x()
f
jeff
>>> def name(n):
... def decorator(fun):
... def wrapper():
... return fun()
... wrapper.name = n
... return wrapper
... return decorator
例如:
>>> @name("hello")
... def f():
... print(f.__name__)
... print(f.name)
...
>>> f()
wrapper
hello
最后一个脚本,第4行,
f
或fun
?好的捕获,应该很有趣,将再次运行此脚本,更正您似乎理解您的装饰程序返回的是包装器,而不是fun
。那个么你们的问题到底是什么呢?wrapper仍然在return fun()
中调用fun,我为name
设置了fun
的属性,为什么它不起作用呢?如果它不应该起作用,为什么x=name(“杰夫”)(f)
起作用,但f=name(“杰夫”)(f)
?但是wrapper
仍然调用fun
,不是吗?另外,为什么x=name(“jeff”)(f)
起作用,但不f=name(“jeff”)(f)
,我会在这两种情况下都替换fun
,我明白了,这是因为f是globall。