파 이 썬 장식 기 (장식 기)
'Built - in Functions (3.6)' 와 'Python 컨 텍스트 관리자' 두 편의 노트 에서 인 테 리 어 초보적인 예 가 있 었 다. 이 편 은 고 로 제 대학의 소 들 의 블 로 그 를 결합 하여 python 에서 인 테 리 어 역할 을 체계적으로 설명 했다.
첫째, 먼저 하나의 통 일 된 개념 을 제시한다
Decorators are functions which modify the functionality of other functions. They help to make our code shorter and more Pythonic.
장식 기 (수식 기 라 고도 부 를 수 있 음) 의 역할 은 다른 함수 의 운영 방식 을 바 꾸 는 것 이다. 이것 은 코드 를 더욱 간결 하고 Pythonic 하 게 할 수 있다.
2. 다음 한 걸음 한 걸음 decorator 에 접근 합 니 다.
우선, 함 수 는 함 수 를 되 돌 릴 수 있 습 니 다. 예 는 다음 과 같 습 니 다.
def hi(name="Leo"):
def greet():
return " !"
def welcome():
return " !"
if name == "Leo":
return greet
else:
return welcome
a = hi()
print(a)
#
# a greet(), name="Leo", return greet,
print(a())
# !
# print(a) greet() , print(a()) , greet() return
그리고 함 수 는 물론 다른 함수 의 매개 변수 로 도 사용 할 수 있 습 니 다.
def hi():
return "hi Leo!"
def doSomethingBeforeHi(func):
print(" "+func.__name__+"() 666")
print(func())
doSomethingBeforeHi(hi)
# hi() 666
# hi Leo!
여기 서 하나의 개념 을 다시 제기 하면 잘 이해 할 수 있다. 즉, Python 의 모든 것 을 object 로 볼 수 있다.사용자 정의 함수 든 기본 데이터 형식 이 든 사용자 정의 클 라 스 나 인 스 턴 스 든 만물 은 대상 입 니 다 (익숙 하 죠).이 대상 들 은 입력 으로 도 되 돌아 갈 수 있다.
장식 기의 핵심 은 바로 위 에서 제시 한 것 이다. 코드 를 더욱 간결 하 게 하기 위해 서 이다.모든 기능 을 한 함수 에 쓰 면 비대 해 보이 기 때문에 일부 기능 을 먼저 쓰 고 다른 함수 로 입력 하면 코드 를 더욱 쉽게 만 들 수 있다.
3. 자, 이제 decorator 를 쓸 수 있 습 니 다.
# coding=utf-8
def decorator(func):
def doSomethingBeforeFunc():
print(" 。")
func()
return doSomethingBeforeFunc
def func():
print(" 。")
func=decorator(func)
func()
# 。
# 。
func 함수 가 '진짜 할 일 은 여기 있 습 니 다' 라 는 말 을 인쇄 하려 고 했 을 뿐 인 데 decorator () 의 처 리 를 거 쳐 행동 에 변화 가 생 겨 한 마디 더 인쇄 한 것 을 볼 수 있 습 니 다. decorator 가 func 를 입력 매개 변수 로 하고 func 를 봉 한 함 수 를 return 했 기 때 문 입 니 다. 이 봉 인 된 함 수 는 func () 의 기능 뿐만 아니 라 print () 도 포함 되 어 있 습 니 다."일 을 하기 전에 다른 것 을 주문 하 세 요.") 의 기능 을 수행 하기 때문에 func = decorator (func) 를 실행 한 후 func 는 원래 의 func 가 아 닙 니 다. 사실은 doSomething BeforeFunc () 입 니 다.
일반적인 장식 기의 호출 방식 은 상기 func = decorator (func) 가 아니 라 @ 기 호 를 사용 합 니 다.
다음 쓰기 방법 은 func 를 정의 하기 전에 @ decorator 호출 장식 기 를 사용 하 는 것 입 니 다. func 를 정의 한 후에 func = decorator (func) 를 실행 한 것 과 같 습 니 다.
# coding=utf-8
def decorator(func):
def doSomethingBeforeFunc():
print(" 。")
func()
return doSomethingBeforeFunc
@decorator
def func():
print(" 。")
func()
# 。
# 。
이 코드 는 위의 코드 와 똑 같은 역할 을 합 니 다. 다만 아래 의 쓰기 가 더 흔 하고 Pythonic (초보 자 에 게 더 우호 적 이지 않 습 니 다).
4. 상기 코드 의 BUG
만약 우리 가 상기 코드 에 decorator 를 사용 한 후의 func 인쇄 name 를 사용한다 면 어떻게 되 겠 습 니까? 쉽게 짐작 할 수 있 는 것 은 doSomething BeforeFunc 라 는 이름 입 니 다. 이것 은 일반적으로 우리 가 원 하 는 것 이 아 닙 니 다.
# coding=utf-8
from functools import wraps
def decorator(func):
@wraps(func)
def doSomethingBeforeFunc():
print(" 。")
func()
return doSomethingBeforeFunc
@decorator
def func():
print(" 。")
func()
print(func.__name__)
# 。
# 。
# func
funtools 의 wraps 방법 을 도입 하면 name 의 디 스 플레이 문 제 를 해결 할 수 있 습 니 다. wraps 가 어떤 메커니즘 을 통 해 이 루어 졌 는 지 에 대해 서 는 원본 코드 가 너무 돌아 서 보지 않 습 니 다. 쉽게 말 하면 wraps 는 func () 가 수식 되 기 전의 각종 내 장 된 속성 을 가 져 올 수 있 습 니 다.
5. Decorator 의 전형 적 인 사용 장면
Python 에서 장식 기 를 사용 하 는 전형 적 인 장면 은 Django 에서 흔히 볼 수 있 는 암호 검증 이 필요 할 때 예 를 들 어:
# coding=utf-8
from functools import wraps
def require_login(func):
@wraps(func)
def new_func(*args, **kwargs):
auth = request.authorization
if not auth or check_auth(auth.username, auth.password):
authenticate()
return func(*args, **kwargs)
return new_func
@require_login
def func():
print(" ...")
위 는 가짜 코드 예제 일 뿐 django 에서 관련 모듈 을 직접 호출 할 수 있 습 니 다.
from django.contrib.auth.decorators import login_required
6. decorator 함수 뿐만 아니 라 decorator 클래스 도 가능 합 니 다.
이전의 예 는 모두 수식 기 함수 입 니 다. 실제 수식 기 는 클래스 일 수도 있 습 니 다. 클래스 가 함수 처럼 호출 될 수만 있다 면 됩 니 다.
# coding=utf-8
class Decorator(object):
def __init__(self , func):
self.func = func
def __call__(self, *args, **kwargs): # __call__
print(" ! !")
return self.func(*args, **kwargs)
@Decorator
def Charge():
print(" !!!")
Charge()
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.