5 분 완전히 파이썬 장식을 파악하기

저자 : Jixinggaozhao는, NetEase는 게임 수석 개발 엔지니어, 설계 및 개발 작업 NetEase는 게임 CDN 자동화 플랫폼의 주요 방향, 뇌 구멍이 오히려 독특한, 비 주류 연구의 다양한 특이한 방법을 고려하지 않는 모든 종류의 것들을 좋아한다.

!

파이썬 장식은 종종 초보자가 배우기 위해, 그것은 종종 혼란을 두려워 두려워하지 아니 작성해야 매개 변수의 종류 잊지 때문에 복잡한 작성, 면접에 자주 방문자, 당신은 읽어 장식의 다양한 이해 모두 사용합니다. 직접 테마 법석!

장식 밴드는 매개 변수, 매개 변수를 작동하지 않습니다

의 함수가 기록을 실행 전후에 달성하기 위해, 간단한 장식을 만들어 보자.

데프 DEC1 (FUNC) :
    인쇄 (FUNC)
    데프 _wrap () :
        인쇄 ( '실행 전')
        R = FUNC ()
        인쇄 ( '실행 후')
        반환 R
    반환 _wrap

@ DEC1
DEF F1 () :
    ( '호 F1')를 인쇄

위는 단지 두 가지 기능이 발견 실행 한 후 출력을 정의하고 있습니다 :

<0x7fa1585f8488의 함수 F1>

밝혀졌다 자세히 살펴보면, 인쇄 문의 첫 번째 출력 할 수 있습니다. 데코레이터가 이상 실행될 때 장식의 기능이 실제로 때문에 하나의 문 DEC1 동등한 @ 실행되지 않았 음을이 쇼 :

DEC1 (F1)

그런 다음 우리는 공식에서 F1을 실행합니다 :

F1 (1)

출력은 참으로 원하는 효과를 달성 다음과 :

실행 전에
통화 F1
실행 후

장식 밴드는 빈 인수와 매개 변수를 작동하지 않습니다

우리는 또한, 무슨 전화를이 방법을 사용하려고 할 다시 데코레이터 추가 매개 변수를주고 싶다 :

@ DEC1 ()

인쇄 오류 :

역 추적 (가장 최근 통화 최종)
<ipython 입력-268-01cf93cf6907>에서 <모듈>
      8 반환 _wrap
      9 
---> 10 @ DEC1 ()
     11 DEF F1 () :
     12 인쇄 ( '호 F1')

형식 오류 : DEC1 (1) 실종은 위치 인수를 필요 : 'FUNC'

그것은이 인수 FUNC 작업을 받아 들일 수 DEC1 필요, 우리는 F2 그것의 기능으로, 변화로 변경했다 :

데프 DEC2 () :
    데프 _wrap (FUNC) :
        인쇄 (FUNC)
        인쇄 ( '실행 전')
        반환 FUNC
    반환 _wrap

@ DEC2 ()
DEF (F2) :
    ( '호 F2')를 인쇄

(F2)

악기는 할 수 있습니다 :

<0x7fa1585af2f0의 함수 F2>
실행 전에
전화 F2

그러나 쓰기를 실행 한 후,이 구조와 원래의 비트 다른,하지만, 그것은 어디? 매우 불행한 사람들은 DEC1, 다른 레이어 기능 dec2x_w, 약간의 현기증을 얻기에 비해, 그것을 F2X라고하는 버전으로 변경되었습니다 :

DEF) (dec2x_w :
    데프 dec2x (FUNC) :
        인쇄 (FUNC)
        데프 _wrap () :
            인쇄 ( '실행 전')
            R = FUNC ()
            인쇄 ( '실행 후')
            반환 R
        반환 _wrap
    반환 dec2x

@ dec2x_w ()
데프 F2X () :
    ( '콜 F2X')를 인쇄

F2X ()

원하는 정말, 그것을 실행하고 참조 :

<0x7fa1585af950에서 기능 F2X>
실행 전에
전화 F2X
실행 후

최대 실행 한 후 나중에 우리는 / 전에 추가하지 않습니다.

매개 변수와 함수, 매개 변수는 장식 없다

이용 약관을 읽고 동의를 할 F2X 함수 매개 변수? 우리는 바 호출, 그것은 비교적 간단 _wrap 매개 변수를 수행하지 않는 것이 플러스가 원하고, 달성 할 수있는 유일한 두 가지 기능으로 돌아 갔다 :

데프 DEC3 (FUNC) :
    인쇄 (FUNC)
    데프 _wrap (PARAM) :
        인쇄 (PARAM)
        R = FUNC (PARAM)
        반환 R
    반환 _wrap

@ DEC3
DEF F3 (a) :
    ( '콜 F3을'A) 인쇄

F3 (1)

아주 결과 출력에 실망 :

<0x7fa158719620의 함수 F3>
1
호 F3 1

함수 인수, 매개 변수 장식

우리는 장식을 달성 아래의 정수를 전달하고 함수 매개 변수가 추가로 전달 될 :

데프 (d_param) dec4_w :
    인쇄 (d_param)
    데프 dec4 (FUNC) :
        인쇄 (FUNC)
        데프 _wrap (PARAM) :
            인쇄 (PARAM)
            R = FUNC (+ 정지 d_param)
            반환 R
        반환 _wrap
    반환 dec4

@ dec4_w (2)
DEF F4 (A) :
    ( '콜 F4'를하는) 인쇄

F4 (1)

1 + 2 = 3 출력 :


<0x7fa1585af598에서 함수 F4>
1
통화 F4 3

통화 찾고 트림에서 음이 파라미터는 3 개 개의 층의 함수 인 것을 제 1 층은 장식의 파라미터는, 상기 제 2 층의 함수이며, 제 3 층은 파라미터의 함수 매우 일정한 배열, 그것의 첫 번째 음이고 (시험)이 법. 두 개의 매개 변수와 함께 다음, 동일 그것을 쓴 :

데프 dec5_w (d_param_1, d_param_2) :
    인쇄 (d_param_1, d_param_2)
    데프 dec5 (FUNC) :
        인쇄 (FUNC)
        데프 _wrap (PARAM) :
            인쇄 (PARAM)
            R = FUNC (+ 정지 + d_param_1 d_param_2)
            반환 R
        반환 _wrap
    반환 dec5

@ dec5_w (2, 3)
데프 F5의 (a) :
    ( '콜 F5'를하는) 인쇄

F5 (1)

출력 1 + 2 + 3 = 6 :

2 3
<0x7fa1586237b8에서 함수 F5>
1
전화 F5 (6)

변수 패러미터의 포지션의 수는, 사용하는 경우 매개 변수로 인수를 *

데프 (* 인수를) dec6_w :
    d_param_1, d_param_2 = 인수
    인쇄 (d_param_1, d_param_2)
    데프 dec6 (FUNC) :
        인쇄 (FUNC)
        데프 _wrap (* 인수) :
            PARAM 인수 = [0]
            인쇄 (PARAM)
            R = FUNC (+ 정지 + d_param_1 d_param_2)
            반환 R
        반환 _wrap
    반환 dec6

@ dec6_w (2, 3)
데프 F6 (A)
    ( '콜 F6'을하는) 인쇄

F6 (1)
인쇄 (F6 .__ name__)

또한, 함수명 F6의 비트의 출력 :

2 3
<0x7fa1586236a8에서 함수 F6>
1
전화 F6 (6)
_싸다

허! 네 어떻게 지방! ! ! F6은 아직 _wrap 이름 안에 어떻게? 두려워 공포, functools 데코레이터 랩은 (다른 장식의 장식의 내부를 넣어) 만족 치료의 다양한 제공 :

functools 수입 랩에서

데프 (* 인수를) dec7_w :
    d_param_1, d_param_2 = 인수
    인쇄 (d_param_1, d_param_2)
    데프 dec7 (FUNC) :
        인쇄 (FUNC)
        @wraps (FUNC)
        데프 _wrap (* 인수) :
            PARAM 인수 = [0]
            인쇄 (PARAM)
            R = FUNC (+ 정지 + d_param_1 d_param_2)
            반환 R
        반환 _wrap
    반환 dec7

@ dec7_w (2, 3)
데프 F7 (A) :
    ( '콜 F7'을하는) 인쇄

F7 (1)
인쇄 (F7 .__ name__)

이것은 정상적인 출력 F7입니다 :

2 3
<0x7fa1585f8510에서 함수 F7>
1
통화 F7 (6)
F7

장식 클래스 (함수 인자, 매개 변수의 장식)

함수 데코레이터 제한은 동일한 메서드 호출, 어떻게 클래스를 변경하는 기능 F7을 사용하여, 너무 많이합니까? emmm ... 조금 큰 혁신 프로젝트는, 그것을 직접 완성 된 제품을 살펴 :

functools 수입 랩에서

클래스 dec8_c :
    데프 (자동, * 인수) __ __init :
        self.d_param_1, self.d_param_2 = 인수
        인쇄 (self.d_param_1, self.d_param_2)
    데프 __call __ (자기, FUNC) :
        인쇄 (FUNC)
        @wraps (FUNC)
        데프 _wrap (PARAM) :
            인쇄 (PARAM)
            R = FUNC (PARAM + self.d_param_1 self.d_param_2 +)
            반환 R
        반환 _wrap

@ dec8_c (2, 3)
데프 F8 (A)
    ( '콜 F8을'A) 인쇄

F8 (1)
인쇄 (F8 .__ name__)

이 같은 효과를 얻을 수 있는지 확인 :

2 3
<0x7fa1585f8048에서 함수 F8>
1
전화 F8 (6)
F8

__call__ 있지만, 그러나 여기가 __init__가 (이 매개 변수의 수를 알 필요가 있기 때문에) 생략 할 수 없습니다 그렇지 않으면이 오류입니다 :

역 추적 (가장 최근 통화 최종)
<ipython 입력-276-1634a47057a2>에서 <모듈>
     (14) 반환 DEC8
     (15) 
---> 16 @ dec8_c (2, 3)
     17 데프 F8 (A) :
     18 인쇄 ( '콜 F8'는)

형식 오류 : dec8_c ()는 인수가없는

또한 발견 될 수 있으며, 단지 두 개의 기능 번째 층은 함수 바디 _wrap에서 직접 제거 된 __call__은 층을 넣어!

장식 클래스 (함수의 매개 변수, 매개 변수없이 데코레이터)

아마 누워 공급뿐만 아니라 처음을 달성하기 위해 원하는 인수와 장식, 그리고 그것을보고 뭔가를 망치 계속 :

클래스 dec9_c :
    데프 (자동, FUNC) __ __init :
        인쇄 (FUNC)
        self.func = FUNC
        자기 .__ name__ = FUNC .__ name__
    데프 __call __ (자기, PARAM) :
        인쇄 (PARAM)
        FUNC = self.func
        R = FUNC (PARAM)
        반환 R

@ dec9_c
데프 F9 (A) :
    ( '콜 F9를'A) 인쇄

F9 (1)
인쇄 (F9 .__ name__)

빨리보고 실행

<0x7fa1585f8730의 함수 F9>
1
전화 F9 (1)
F9

이봐, F9 기능 이름에서하지 않는 직접 인쇄 할 수 있습니다 그것의 @wraps! 어, 좀 더 자세히 살펴,이 표현은 약간 다른 아 것 같다 :

  • 의 dec8_c  초기화  매개 변수 데코레이터와 함께,하지만 장식과 dec9_c 자신의 함수이다!
  • 따라서, 함수 호출의 실제 이름도있을 수  초기화  오, 그것을 통과!
  • 그리고  통화  기능은 간단하고 많은, 정말 아무 인수가 너무 큰 차이가없는 것 같다!

전자는 함수 장식에서 반환되는 함수 자체가 있기 때문에 여기 구현에 (괄호 및 매개 변수) 요약 (괄호없이) 장식 함수 이름 양식을 사용 함수 호출을 수행하는, 다른 기능. 이 DEC1 직접 통화 F2 때문에, 그리고 DEC2 GET 처음 실행 기능, 호출 F2에 다음 함수가 반환, 또한 실행 한 후 기록에 비해 F1을 F2의 부족에 대한 이유입니다. 이 __call__에 대한 호출이기 때문에 장식 클래스와 함께이 문제를 해결할 수 있습니다, 단지 자신의 정의 그것을 클릭.

F9는 두 가지 기능은 위의 F1 및 간결하게 기록 될 수없는 물품 하는가? 물론 당신은 대법 __new__ 사용할 수 있습니다 :

functools 수입 랩에서

클래스 dec9x_c :
    __ 데프 __new (자기, FUNC) :
        인쇄 (FUNC)
        @wraps (FUNC)
        데프 dec9x (PARAM) :
            인쇄 (PARAM)
            R = FUNC (PARAM)
            반환 R
        반환 dec9x

@ dec9x_c
데프 f9x (A) :
    ( '콜 f9x을'A) 인쇄

f9x (1)
인쇄 (f9x .__ name__)

이것은 (__call__ 기능을 정의) 플레이를 호출하지 않는, 함수 호출을 피할 것, 그것은 간단히 살펴했다 :

<0x7fa158623bf8에서 기능 f9x>
1
전화 1 f9x
f9x

추천

출처www.cnblogs.com/7758520lzy/p/12188018.html