파 이 썬 장식 기 (장식 기)

http://book.pythontips.com/en/latest/decorators.html
'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()

좋은 웹페이지 즐겨찾기