파이썬 장식기는 왜 이해하기 어려워요?
그러나 왜 초보자가 장식기에 대한 이해가 이렇게 어려운지, 나는 본질적으로 파이톤 함수에 대한 이해가 제대로 되지 않는다고 생각한다. 왜냐하면 장식기는 본질적으로 함수이기 때문이다.
함수 정의
장식기를 이해하기 전에 함수의 작업 원리를 이해해야 한다. 우리는 가장 간단한 함수 정의부터 시작한다.
def foo(num):
return num + 1
위에서 하나의 함수를 정의했는데 이름은
foo
이고 foo
도 변수 이름으로 이해할 수 있다. 이 변수는 하나의 함수 대상을 가리킨다호출 함수는 함수 이름에 괄호를 붙이고 필요한 매개 변수를 전달하기만 하면 된다. (함수가 정의할 때 매개 변수가 있다면)
value = foo(3)
print(value) # 4
변수 이름
foo
은 현재
함수 대상을 가리키지만, 다른 함수도 가리킬 수 있다.def bar():
print("bar")
foo = bar
foo() # bar
함수를 반환값으로 삼다
Python에서는 모든 것이 객체이고 함수도 예외가 아닙니다. 함수는 정수처럼 다른 함수의 반환값으로 사용할 수 있습니다. 예를 들어 다음과 같습니다.
def foo():
return 1
def bar():
return foo
print(bar()) #
print(bar()()) # 1
#
print(foo()) # 1
호출 함수bar()의 반환값은 함수 대상이다. 반환값은 함수이기 때문에 우리는 반환값을 계속 호출할 수 있다. (기억해라. 호출 함수는 함수 이름 뒤에
()
호출bar()()
은 호출foo()
에 해당한다. 변수foo가 가리키는 대상과bar()의 반환값은 같은 대상이기 때문이다.함수를 매개 변수로 삼다
함수는 정수와 같이 함수의 매개 변수로 사용할 수도 있다. 예를 들어 다음과 같다.
def foo(num):
return num + 1
def bar(fun):
return fun(3)
value = bar(foo)
print(value) # 4
함수
bar
는 하나의 매개 변수를 수신한다. 이 매개 변수는 호출할 수 있는 함수 대상으로 함수foo
를 bar
에 전달할 때foo와fun 두 변수의 이름이 같은 함수 대상을 가리키기 때문에fun(3)을 호출하는 것은foo(3)를 호출하는 것과 같다.함수 중첩
함수는 매개변수 및 반환값뿐만 아니라 다음과 같은 네스트된 함수로 다른 함수에도 정의할 수 있습니다.
def outer():
x = 1
def inner():
print(x)
inner()
outer() # 1
inner
중첩 함수로 외부 함수의 변수에 접근할 수 있으며 outer 함수를 호출할 때 세 가지 일이 발생했다.x
에 1inner
를 정의합니다. 이 함수는 3단계가방을 닫다
다시 한 번 예를 살펴보자.
def outer(x):
def inner():
print(x)
return inner
closure = outer(1)
closure() # 1
마찬가지로 플러그인 함수입니다. 조금만 바꾸면 국부 변수 x를 매개 변수로 전달합니다. 플러그인 함수는 함수에서 직접 호출되지 않고 되돌아오는 값으로 되돌아옵니다. 여기의closure는 패키지입니다. 본질적으로 패키지는 함수입니다. 패키지는 자유 변수(x)의 함수(inner)를 인용한 함수입니다.
장식기
계속해서 아래를 내려다보다.
def foo():
print("foo")
위의 이 함수는 아마도 역사상 가장 간단한 업무 코드일 것이다. 비록 쓸모가 없지만 문제를 설명할 수 있으면 된다.이 함수를 실행할 때 로그를 추가해야 하는 새로운 요구 사항이 있습니다.
def foo():
print(" ")
print("foo")
print(" ")
기능이 실현되는 유일한 문제는 그것이 원래의 코드에 침입하여 로그 논리를 추가해야 한다는 것이다. 만약에 이런 함수가 수십 개 더 있다면 로그를 추가해야 한다. 분명히 이런 코드는 조금도 파이토닉이 아니다.그렇다면 업무 코드를 수정하지 않는 앞당겨 로그 기능을 실현할 수 있을까?정답은 장식기다.
def outer(func):
def inner():
print(" ")
func() #
print(" ")
return inner
def foo():
print("foo")
foo = outer(foo)
foo()
나는 foo 함수 안의 어떤 논리도 수정하지 않았고, 단지foo 변수에 다시 값을 부여하여 새로운 함수 대상을 가리켰다.마지막으로 foo () 를 호출하면 로그를 출력할 수 있을 뿐만 아니라 업무 논리도 실행됩니다.이제 그것의 집행 절차를 분석해 봅시다.
여기의 outer 함수는 사실 하나의 장식기이다. 장식기는 함수를 매개 변수로 하고 새로운 함수를 되돌려주는 클립이다. 본질적으로 장식기도 함수이다.outer 함수의 반환값은 inner 함수입니다. inner 함수에서 로그 조작을 실행하는 것 외에 업무 코드도 있습니다. 이 함수는foo 변수에 다시 값을 부여한 후foo()를 호출하면 inner()를 호출하는 것과 같습니다.
foo 재할당 전:
값을 재지정하면 foo = outer(foo)
또한 파이썬은 함수의 정의에 사용되는 구문 설탕@을 장식기에 제공합니다.
@outer
def foo():
print("foo")
foo()
이렇게 하면 수동으로
foo
에 값을 다시 부여하는 절차를 줄일 수 있다.여기까지 장식기에 대해 이해가 됐나요?물론 장식기는 더욱 복잡할 수 있다. 예를 들어 파라미터를 받아들일 수 있는 장식기, 유형을 바탕으로 하는 장식기 등이다.다음 편은 장식기의 응용 장면을 쓸 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.