Python 装饰程序不更改目录()
使用Python装饰程序时不使用Python 装饰程序不更改目录(),python,python-2.7,decorator,python-decorators,Python,Python 2.7,Decorator,Python Decorators,使用Python装饰程序时不使用 @functools.wraps(function) 更改原始函数的\uuuu doc\uuuu,\uuuu name\uuuu,帮助,这是可以理解的,因为decorator很简单 fun=decorate(fun) 但是为什么它不改变这个函数的dir(fun)呢?它不也应该改变吗 例如: def wow(func): def __wow(): return func() return __wow @wow def fun(
@functools.wraps(function)
更改原始函数的\uuuu doc\uuuu
,\uuuu name\uuuu
,帮助
,这是可以理解的,因为decorator很简单
fun=decorate(fun)
但是为什么它不改变这个函数的dir(fun)呢?它不也应该改变吗
例如:
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)
的乐趣。name给出了decorator的乐趣。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']
您怎么知道这些是原始函数的属性名,还是包装函数的属性名?这两种情况下的列表都完全相同。您似乎错过了装饰器的一个关键步骤。在函数
fun
上使用decorator@decoration
可以做到以下几点:
fun = decorate(fun)
但是不要坚持到底fun
现在绑定到装饰器的返回值
你说:
Python decorators[…]更改原始函数的\uuuuu doc\uuuuuuuuu
,\uuuuu name\uuuuuuuuuu
,帮助
事实并非如此。原始的未修饰函数保持不变。它仍然具有相同的\uuuuu doc\uuuuuu
、相同的\uuuu名称\uuuuuuuuu
,等等。但是,装饰程序返回的对象现在绑定到原始名称,很可能具有不同的名称或docstring。毕竟,它很可能是一个完全不同的对象
在示例中,您从decorator返回了\uuuwow
,因此Python将该对象分配给fun
fun
在这里只是一个名称,它引用了装饰器的结果。原来的fun
功能不再通过该名称提供;在这里,您决不会检查原始的、未修饰的函数
因此,在名称上使用dir()
意味着它应用于fun
现在绑定到的任何东西,这就是装饰程序生成的\uuwow
函数。在fun
上设置属性,在同一个函数对象上设置属性。所有属性都反映了这一点
您可能会发现逐步了解Python所做的事情并将这些步骤可视化是很有帮助的。看这个,;它向您展示了fun
最后引用的内容(以及原始函数对象的结束位置):
您希望有什么不同?@vks:您正在对装饰结果应用属性和
dir()
。您只需在该对象上设置一个新属性,当然dir()
将包含该属性。我也要求您明确说明:您只在dir()
中突出显示'b'
。你没想到它会在那里吗?请解释输出的惊人之处以及为什么。函数是对象。您从decorator返回了\uuuuwow
,因此Python将该对象分配给fun
fun
在这里只是一个名称,它引用了装饰器的结果。如果您添加一个类似fun.c=1
的属性,那么您可以查看yourself@vks:您确实需要在函数中添加一个。用代码向我们展示这些步骤,并解释这些步骤产生的输出如何与您的预期输出不匹配。