Python 은 어떻게 장식 기 를 클래스 로 정의 합 니까?
장식 기 를 사용 하여 함 수 를 포장 하고 싶 지만 호출 가능 한 인 스 턴 스 를 되 돌려 주 기 를 바 랍 니 다.당신 의 장식 기 가 클래스 정의 의 내부 와 외부 에서 동시에 작업 할 수 있 도록 해 야 합 니 다.
해결 방안
장식 기 를 인 스 턴 스 로 정의 하기 위해 서 는 가 실현 되 었 는 지 확인 해 야 합 니 다.call__() 와get__() 방법예 를 들 어 아래 코드 는 하나의 종 류 를 정의 합 니 다.다른 함수 에 간단 한 기록 층 을 설치 합 니 다.
import types
from functools import wraps
class Profiled:
def __init__(self, func):
wraps(func)(self)
self.ncalls = 0
def __call__(self, *args, **kwargs):
self.ncalls += 1
return self.__wrapped__(*args, **kwargs)
def __get__(self, instance, cls):
if instance is None:
return self
else:
return types.MethodType(self, instance)
당신 은 그것 을 일반적인 장식 기로 사용 할 수 있 습 니 다.클래스 안 이나 밖에서 도 사용 할 수 있 습 니 다.
@Profiled
def add(x, y):
return x + y
class Spam:
@Profiled
def bar(self, x):
print(self, x)
대화 형 환경 에서 의 사용 예시:
>>> add(2, 3)
5
>>> add(4, 5)
9
>>> add.ncalls
2
>>> s = Spam()
>>> s.bar(1)
<__main__.Spam object at 0x10069e9d0> 1
>>> s.bar(2)
<__main__.Spam object at 0x10069e9d0> 2
>>> s.bar(3)
<__main__.Spam object at 0x10069e9d0> 3
>>> Spam.bar.ncalls
3
토론 하 다.장식 기 를 클래스 로 정의 하 는 것 은 보통 간단 하 다.그러나 여기 에는 아직도 세부 적 인 설명 이 필요 하 다.특히 그것 을 실례 적 인 방법 에 작용 하고 싶 을 때.
우선,funtools.wraps()함수 의 역할 은 이전 과 마찬가지 로 포장 함수 의 메타 정 보 를 호출 가능 한 인 스 턴 스 로 복사 합 니 다.
그 다음으로 위의 를 무시 하기 쉽다.get__() 방법만약 그것 을 무시 하고 다른 코드 가 변 하지 않 고 다시 실행 된다 면,인 테 리 어 된 실례 방법 을 호출 할 때 이상 한 문제 가 발생 하 는 것 을 발견 할 수 있 을 것 이다.예 를 들 면:
>>> s = Spam()
>>> s.bar(3)
Traceback (most recent call last):
...
TypeError: bar() missing 1 required positional argument: 'x'
오류 원인 은 방법 함수 가 한 클래스 에서 찾 을 때 그들의get__() 방법 은 설명 기 프로 토 콜 에 따라 호출 되 었 으 며,8.9 소절 에 이미 설명 기 프로 토 콜 을 설명 하 였 다.여기 있다!get__() 바 인 딩 방법 대상 을 만 드 는 것 이 목적 입 니 다.다음은 하나의 예 로 밑바닥 원 리 를 보 여 준다.
>>> s = Spam()
>>> def grok(self, x):
... pass
...
>>> grok.__get__(s, Spam)
<bound method Spam.grok of <__main__.Spam object at 0x100671e90>>
>>>
__get__() 방법 은 귀속 방법의 대상 이 정확하게 생 성 될 수 있 도록 확보 하기 위 한 것 이다.type.MethodType()수 동 으로 바 인 딩 방법 을 만 듭 니 다.인 스 턴 스 가 사 용 될 때 만 바 인 딩 방법 이 생 성 됩 니 다.이 방법 이 클래스 에 접근 하 는 것 이 라면get__() 인 스 턴 스 매개 변 수 는 None 으로 설정 되 어 Profiled 인 스 턴 스 자 체 를 직접 되 돌려 줍 니 다.이렇게 하면 우 리 는 그것 의 ncalls 속성 을 추출 할 수 있다.혼란 을 피하 고 싶다 면 폐쇄 와 nonlocal 변 수 를 사용 한 다른 장식 기 를 고려 해 보 세 요.이것 은 9.5 소절 에서 말 했 습 니 다.예 를 들 면:
import types
from functools import wraps
def profiled(func):
ncalls = 0
@wraps(func)
def wrapper(*args, **kwargs):
nonlocal ncalls
ncalls += 1
return func(*args, **kwargs)
wrapper.ncalls = lambda: ncalls
return wrapper
# Example
@profiled
def add(x, y):
return x + y
이 방식 은 이전 효과 와 거의 같 습 니 다.ncalls 에 대한 방문 을 제외 하고 현재 속성 으로 연 결 된 함수 로 이 루어 집 니 다.예 를 들 어:
>>> add(2, 3)
5
>>> add(4, 5)
9
>>> add.ncalls()
2
>>>
이상 은 Python 이 인 테 리 어 를 클래스 로 정의 하 는 방법 에 대한 상세 한 내용 입 니 다.Python 이 인 테 리 어 를 클래스 로 정의 하 는 데 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Python의 None과 NULL의 차이점 상세 정보그래서 대상 = 속성 + 방법 (사실 방법도 하나의 속성, 데이터 속성과 구별되는 호출 가능한 속성 같은 속성과 방법을 가진 대상을 클래스, 즉 Classl로 분류할 수 있다.클래스는 하나의 청사진과 같아서 하나의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.