碰巧,因爲你的裝飾器在包裝上設置了屬性。當第一個裝飾在它的包裝器上設置屬性時,它將包裝器傳遞給第二個裝飾器,它在第一個包裝器上添加另一個包裝器,並在第二個包裝器上設置屬性。所以你最終得到第二個包裝。
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