데코레이터가 래퍼의 특성을 설정하기 때문에 발생합니다. 첫 번째 데코 레이팅이 래퍼에 속성을 설정하면 래퍼를 두 번째 데코레이터로 전달하고 첫 번째 데코레이터 위에 다른 래퍼를 추가하고 두 번째 래퍼에 특성을 설정합니다. 따라서 두 번째 래퍼로 끝납니다.
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'는'test'가 아닌 * 데코 레이팅 된 * 함수를 매개 변수로 기대해야합니다. –
문체적인 측면에서 [PEP8 표준] (https://www.python.org/dev/peps/pep-0008/#indentation)은 들여 쓰기를 위해 4 칸을 요구합니다. 문법적으로 1 개만 작동하지만 읽는 것은 정말 어렵고 다른 사람들과 코드를 공유하기가 어렵습니다. –
예, 그렇습니다. t2의 입력을 처리 (함수)하면 속성 t1이 표시됩니다. 그러나, 만약 내가 dir (test)하면, 나는 t2 만 볼 수있다 (t1은 지워진다). – Sonny