在没有
的情况下使用Python装饰器@functools.wraps(function)
更改原始功能的__doc__
,__name__
,help
,这可以理解为装饰器只是
fun=decorate(fun)
但为什么它不改变dir(有趣)的功能?不应该改变吗?
例如:
def wow(func):
def __wow():
return func()
return __wow
@wow
def fun():
print "yes"
fun.b=1
print fun.__name__
print dir(fun)
输出
__wow => name of decorator
[... '__sizeof__', '__str__', '__subclasshook__', 'b', 'func_closure', ...]
^^
如果你看到这里,当我们打印name
时它是decorator
,但当我们打印dir
fun
b
时,b
就在那里。那么为什么dir(decorator)
在那里呢?不应该$scope.combineParts = function(part1, part2) {
var merged = angular.copy( part1 );
for ( key in part1 )
{
if ( part2.hasOwnProperty(key) )
merged[key].push.apply(merged[key], part2[key])
}
return merged;
}
有趣。名称给出了装饰者
答案 0 :(得分:2)
你似乎错过了装饰者的关键一步。你确实在函数@decorate
上使用装饰器fun
来做到这一点:
fun = decorate(fun)
然后不要跟进。 fun
现在绑定到装饰器的返回值。
你说:
Python装饰器[...]更改原始函数的
__doc__
,__name__
,help
事实并非如此。原始的,未修饰的功能没有变化。它仍然具有相同的__doc__
,相同的__name__
等。来自装饰器的返回的对象,现在绑定到原始名称,但是,可能有不同的名称或docstring。毕竟,它可能完全是不同的对象。
在您的示例中,您从装饰器返回__wow
,因此Python将该对象分配给fun
。 fun
这里只是一个名称,一个引用装饰器的结果。 原始 fun
功能不再通过该名称提供;在没有点你在这里检查原始的,未修饰的功能。
因此,在名称 dir()
上使用fun
表示它适用于现在绑定的任何fun
,即__wow
由装饰者产生的功能。在fun
上设置属性,在同一个函数对象上设置属性。所有属性都反映了这一点。
您可能会发现逐步完成Python的工作并将这些步骤可视化很有帮助。见Python Tutor visualisation;它向您显示最终的fun
引用(以及原始函数对象最终的位置):
答案 1 :(得分:0)
dir()
将返回如下内容:
>>> dir(f)
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
您如何判断这些是原始函数的属性名称还是包装函数的属性名称?在任何一种情况下,它都是完全相同的列表。