다음은 Python에서 함수 장식이 작동하는 방법에 대한 간단한 예입니다. 의 생명, 우주, 그리고 모든 것의 궁극적 인 질문에 대한 답 반환하는 함수 보자 :
>>> get_answer
<function get_answer at 0x7f9c4f8bac08>
>>> get_answer()
42
: 당신이 get_answer
기호를 살펴보면
def get_answer():
return 42
, 당신은 그것을 볼 것은 함수의 이제 하드 코딩 된 응답을 반환하는 것이 다른 우주에서 실제로 과학적이거나 재사용이 가능하지 않으며 함수가 실제로 우주의 실제 매개 변수를 기반으로 계산해야한다고 결정합시다. 따라서 새 기능 compute_answer
이 도입되었고 get_answer
은 새로운 기능을 위해 더 이상 사용되지 않습니다. 사용 중단의 사용자에게 경고하기 위해 몇 가지 할 수 있습니다 : 소스 코드가 경고를 제공하기 위해 수정할 수
: 그것의 소스 코드의 변화를 소개로
def get_answer():
print("WARNING: Function get_answer is deprecated")
return 42
이 못생긴 기능. 여기 어떻게 우리가 deprecated
기능에 기능을 전달한다는 것입니다 후자 빌드하고 래퍼를 반환 무엇
def deprecated(func):
def show_deprecated():
print("WARNING: Function {} is deprecated".format(func.__name__))
return func()
return show_deprecated
: 더 좋은 방법은 함수를 래핑하는 것입니다. 래퍼는 호출시 func
인수의 값을 캡처 (기억)하는 중첩 된 show_deprecated
함수의 인스턴스입니다. 이것은 closure라고하며 함수형 프로그래밍의 초석 중 하나입니다.
우리는 지금 경로 deprecated
을 통해 get_answer
에 대한 호출은 함수의 소스 코드에서 아무 것도 변경하지 않고 자동으로 중단 메시지를 얻을 수 있습니다
>>> get_answer_dep = deprecated(get_answer)
>>> get_answer_dep()
WARNING: Function get_answer is deprecated
42
우리는 또한 랩 버전으로 get_answer
를 오버라이드 (override) 할 수있는 모든 있도록 이 호출은 래퍼를 통해 라우팅되지 얻을 :이 시점 하나에서
>>> get_answer = deprecated(get_answer)
>>> get_answer()
WARNING: Function get_answer is deprecated
42
는 더 이상 get_answer
의 원래 겹쳐지지 않은 코드에 액세스 할 수 있습니다. 그것은 여전히 존재하며 래퍼 함수에 의해 호출되지만, 우리가 단순히 그것을 직접 호출 할 수있는 공개적으로 볼 수있는 심볼은 없습니다 (래퍼의 인트로 스펙 션을 통해 원래 코드를 호출 할 수는 있지만, 우리가 모르는 척합니다 그것을하는 방법).
:
help(get_answer)
를 호출하면 실제로
show_deprecated
의 문서 문자열을 표시, 개체 자체의
>>> get_answer
<function show_deprecated at 0x7f9c4218b140>
표시 help(something)
이래 __doc__
특성 : 당신이 지금 get_answer
기호를 살펴보면, 실제로는 show_deprecated
기능의 인스턴스
>>> help(get_answer)
Help on function show_deprecated in module __main__:
show_deprecated()
각 비추천 함수 뒤에 name = deprecated(name)
을 쓰는 것은 약간 지루합니다.
@deprecated
def get_answer()
return 42
@deprecated
구문 기능 장식라고 : 파이썬은 짧은 컷 구문을 제공하는 이유입니다. 그것은 단순히 함수의 정의 후,이 경우 deprecated()
에서 장식 함수에 대한 호출을 삽입하고 함수 이름을 베어링 기호에 결과를 할당 할 인터프리터를 지시, 즉 :
@foo
def bar():
...
은 동일합니다 : source code에서 본
def bar():
...
bar = foo(bar)
unittest
모듈은 상기 장식 구를 활용하지 않는다.
그 help()
은 원래의 래퍼 함수 대신 디버깅하는 동안 버머입니다. 다행스럽게도 함수 이름과 문서 문자열은 실제로 쓰기 가능한 속성이므로 원래 함수에서 래퍼로 복사 할 수 있으므로 help()
으로 표시된 이름과 설명서 문자열을 유지할 수 있습니다. Python은 functools
모듈과 함께 제공되며 정확하게 수행하는 데코레이터 wraps
을 제공합니다. 우리가 지금 get_answer
기능, 이름, 문서를 감싸는 경우
from functools import wraps
def deprecated(func):
@wraps(func)
def show_deprecated():
print("WARNING: Function {} is deprecated".format(func.__name__))
return func()
return show_deprecated
, 모듈의 특성은 유지됩니다 : 데코레이터는 중첩 (래퍼) 함수에서 사용되는
>>> get_answer = deprecated(get_answer)
>>> help(get_answer)
Help on function get_answer in module __main__:
get_answer()
어떻게 기능 장식의 그 Python에서 작동합니다. 'deprecated_func'는 내부에서 선언되고 함수 데코레이터'_deprecate'에 의해 반환되는 래퍼 함수입니다. –
@ hristo-iliev 답변 해 주셔서 감사합니다.이 점을 이해하지 못하고 일부 사례는 괜찮을 것입니다. – abrasadera