具有函数属性的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。