碰巧,因为你的装饰器在包装上设置了属性。当第一个装饰在它的包装器上设置属性时,它将包装器传递给第二个装饰器,它在第一个包装器上添加另一个包装器,并在第二个包装器上设置属性。所以你最终得到第二个包装。
In [3]: def decorator_a(fn):
...: def wrapper(*args, **kwargs):
...: return fn(*args, **kwargs)
...: print("I'm setting the attribute on function {}".format(id(wrapper)))
...: setattr(wrapper, "attr1", True)
...: return wrapper
...:
In [4]: def decorator_b(fn):
...: def wrapper(*args, **kwargs):
...: return fn(*args, **kwargs)
...: print("I'm setting the attribute on function {}".format(id(wrapper)))
...: setattr(wrapper, "attr2", True)
...: return wrapper
...:
In [5]: first_time_decorated = decorator_a(lambda x: x)
I'm setting the attribute on function 4361847536
In [6]: second_time_decorated = decorator_b(first_time_decorated)
I'm setting the attribute on function 4361441064
您可以通过设置功能的所有属性解决这个正在装修的包装
In [14]: def decorator_a(fn):
...: def wrapper(*args, **kwargs):
...: return fn(*args, **kwargs)
...: setattr(wrapper, "attr1", True)
...: for attribute in set(dir(fn)) - set(dir(wrapper)):
...: setattr(wrapper, attribute, getattr(fn, attribute))
...: return wrapper
...:
In [15]: def decorator_b(fn):
...: def wrapper(*args, **kwargs):
...: return fn(*args, **kwargs)
...: setattr(wrapper, "attr2", True)
...: for attribute in set(dir(fn)) - set(dir(wrapper)):
...: setattr(wrapper, attribute, getattr(fn, attribute))
...: return wrapper
...:
In [16]: first_time_decorated = decorator_a(lambda x: x)
In [17]: second_time_decorated = decorator_b(first_time_decorated)
In [18]: second_time_decorated.attr1
Out[18]: True
In [19]: second_time_decorated.attr2
Out[19]: True
't1'“包装”功能'test',然后't2'“包装”的函数由't1'返回。因此't2'应该期望一个*修饰*函数作为它的参数 - 而不是'测试'。 –
作为一种文体学观点,[PEP8标准](https://www.python.org/dev/peps/pep-0008/#indentation)要求4个空格用于缩进。虽然只有1个在语法上起作用,但它很难阅读,并且很难与其他人分享您的代码。 –
是的,我明白了。如果我dir(函数)t2的输入,我看到属性t1。但是,如果我dir(测试),我只看到t2(t1被删除)。 – Sonny