Python 함수 장식 기 사용 튜 토리 얼
다음 예제 에 서 는 장식 기,출력 함수 의 운행 시간 을 정의 합 니 다.
함수 장식 기와 패 킷 이 밀접 하 게 결합 되 어 있 으 며,인삼 func 에 들 어가 면 장식 함 수 를 대표 하 며,자유 변 수 를 통 해 연 결 된 후 함 수 를 호출 하여 결 과 를 되 돌려 줍 니 다.
clock 장식 기 사용:
import time
from clockdeco import clock
@clock
def snooze(seconds):
time.sleep(seconds)
@clock
def factorial(n):
return 1 if n < 2 else n*factorial(n-1)
if __name__=='__main__':
print('*' * 40, 'Calling snooze(.123)')
snooze(.123)
print('*' * 40, 'Calling factorial(6)')
print('6! =', factorial(6)) # 6! 6
출력 결과:이것 은 장식 기의 전형 적 인 행위 이다.장 식 된 함 수 를 새로운 함수 로 바 꾸 고 두 사람 은 같은 매개 변 수 를 받 아들 이 며 장 식 된 함수 가 되 돌아 가 야 할 값 을 되 돌려 주 는 동시에 추가 작업 도 할 수 있다.
주의해 야 할 것 은 factorial()은 재 귀 함수 입 니 다.결 과 를 보면 재 귀 할 때마다 장식 기 를 사용 하여 운행 시간 을 인쇄 했 습 니 다.이것 은 다음 과 같은 코드 때 문 입 니 다.
@clock
def factorial(n):
return 1 if n < 2 else n*factorial(n-1)
등가:
def factorial(n):
return 1 if n < 2 else n*factorial(n-1)
factorial = clock(factorial)
factorial 은 clock(factorial)함수 의 반환 값,즉 장식 기 내부 함수 clocked 를 참조 합 니 다.factorial(n)을 호출 할 때마다 clocked(n)를 실행 합 니 다.인 테 리 어
@d1
@d2
def f():
print("f")
등가:
def f():
print("f")
f = d1(d2(f))
매개 변수 화 장식 기어떻게 장식 기 에 인 자 를 받 아들 입 니까?정 답 은 장식 기 공장 함 수 를 만 들 고 인 자 를 전달 하 며 장식 기 를 되 돌려 주 고 장식 할 함수 에 적용 하 는 것 이다.
예 는 다음 과 같다.
registry = set()
def register(active=True):
def decorate(func):
print('running register(active=%s)->decorate(%s)'
% (active, func))
if active:
registry.add(func)
else:
registry.discard(func)
return func
return decorate
@register(active=False)
def f1():
print('running f1()')
#
@register()
def f2():
print('running f2()')
def f3():
print('running f3()')
register 는 장식 기 공장 함수 입 니 다.선택 가능 한 매개 변수 active 를 받 아들 이 는 기본 값 은 True 이 고 내부 에 장식 기 decorate 를 정의 하여 되 돌려 줍 니 다.주의해 야 할 것 은 장식 기 공장 함수 입 니 다.파 라 메 터 를 전달 하지 않 더 라 도 작은 괄호 호출 을 추가 해 야 합 니 다.예 를 들 어@register().예 를 하나 더 보 자.
import time
DEFAULT_FMT = '[{elapsed:0.8f}s] {name}({args}) -> {result}'
#
def clock(fmt=DEFAULT_FMT):
#
def decorate(func):
#
def clocked(*_args):
t0 = time.time()
# _result
_result = func(*_args)
elapsed = time.time() - t0
name = func.__name__
args = ', '.join(repr(arg) for arg in _args)
result = repr(_result)
# **locals() clocked
print(fmt.format(**locals()))
return _result
return clocked
return decorate
if __name__ == '__main__':
@clock()
def snooze(seconds):
time.sleep(seconds)
for i in range(3):
snooze(.123)
이것 은 전형 적 인 함수 장식 기 에 매개 변수 fmt 를 추가 한 것 으로 장식 기 공장 함수 에 포 함 된 세트 를 추가 하 였 으 며,예제 에는 모두 3 개의 def 가 있다.표준 라 이브 러 리 의 장식 기
Python 은 장식 방법 에 사용 할 세 가지 함 수 를 내장 하 였 습 니 다:property,classmethod,staticmethod.이것 은 미래의 글 에서 말 할 것 입 니 다.본 고 는 funtools 중의 세 가지 장식 기 를 소개 한다.funtools.wraps,funtools.lrucache 와 funtools.singledispatch.
functools.wraps
Python 함수 장식 기 가 실 현 될 때 장 식 된 함 수 는 이미 다른 함수(함수 명 등 함수 속성 이 변 경 됩 니 다)입 니 다.영향 을 주지 않 기 위해 Python 의 funtools 패키지 에 wraps 라 는 장식 기 를 제공 하여 이러한 부작용 을 제거 합 니 다(기 존 함수 의 이름과 함수 속성 을 유지 할 수 있 습 니 다).
예제,wraps 를 추가 하지 않 음:
def my_decorator(func):
def wrapper(*args, **kwargs):
'''decorator'''
print('Calling decorated function...')
return func(*args, **kwargs)
return wrapper
@my_decorator
def example():
"""Docstring"""
print('Called example function')
print(example.__name__, example.__doc__)
# wrapper decorator
wraps 추가:
import functools
def my_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
'''decorator'''
print('Calling decorated function...')
return func(*args, **kwargs)
return wrapper
@my_decorator
def example():
"""Docstring"""
print('Called example function')
print(example.__name__, example.__doc__)
# example Docstring
functools.lru_cachelru 는 Least Recently Used 의 줄 임 말로 최적화 기술 로 시간 이 걸 리 는 함수 의 결 과 를 저장 하여 같은 매개 변수 가 들 어 올 때 중복 계산 하지 않도록 합 니 다.
예시:
import functools
from clockdeco import clock
@functools.lru_cache()
@clock
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-2) + fibonacci(n-1)
if __name__=='__main__':
print(fibonacci(6))
재 귀 알고리즘 을 최적화 하면 실행 시간 이 반 으로 줄어든다.주의,lrucache 는 두 개의 선택 가능 한 매개 변 수 를 사용 하여 설정 할 수 있 습 니 다.서명 은 다음 과 같 습 니 다.
functools.lru_cache(maxsize=128, typed=False)
4.567917.maxsize:최대 저장 수량,캐 시 가 가득 차 면 오래된 결 과 는 버 려 집 니 다4.567917.typed:True 로 설정 하면 서로 다른 매개 변수 유형 에서 얻 은 결 과 를 분리 하여 저장 합 니 다.즉,보통 같은 부동 소수점 과 정형 매개 변수(예 를 들 어 1 과 1.0)를 구분 합 니 다functools.singledispatchPython 3.4 의 새로운 문법 은 함수 중의 대량의 if/elif/elif 를 최적화 하 는 데 사용 할 수 있 습 니 다.@singledispatch 장식 을 사용 하 는 일반 함 수 는 범 함수 가 됩 니 다.첫 번 째 매개 변수 유형 에 따라 같은 동작 을 수행 하 는 함수 입 니 다.그래서 싱글 디 스 패 치,단일 분파 라 고 합 니 다.
여러 매개 변수 에 따라 분 파 를 하면 다 분 파 를 하 는 것 이다.
예 를 들 어 HTML 을 생 성하 고 서로 다른 유형의 Python 대상 을 표시 합 니 다.
import html
def htmlize(obj):
content = html.escape(repr(obj))
return '<pre>{}</pre>'.format(content)
Python 은 리 셋 방법 이나 함 수 를 지원 하지 않 기 때문에 서로 다른 서명 으로 htmlize 의 변 체 를 정의 할 수 없습니다.htmlize 를 하나의 분파 함수 로 만 들 수 있 습 니 다.if/elif/elif 를 사용 하여 전문 적 인 함 수 를 호출 할 수 있 습 니 다.예 를 들 어 htmlizestr、htmlize_int 등.시간 이 길 어 지면 htmlize 가 커 지고 각 전문 함수 와 의 결합 도 긴밀 하여 모듈 확장 에 불편 합 니 다.@singledispatch 는 심사숙고 한 끝 에 표준 라 이브 러 리 에 가입 하여 이러한 문 제 를 해결 합 니 다.
from functools import singledispatch
from collections import abc
import numbers
import html
@singledispatch
def htmlize(obj):
# if/elif/elif
content = html.escape(repr(obj))
return '<pre>{}</pre>'.format(content)
@htmlize.register(str)
def _(text):
#
content = html.escape(text).replace('
', '<br>
')
return '<p>{0}</p>'.format(content)
@htmlize.register(numbers.Integral)
def _(n):
#
return '<pre>{0} (0x{0:x})</pre>'.format(n)
@htmlize.register(tuple)
@htmlize.register(abc.MutableSequence)
def _(seq):
#
inner = '</li>
<li>'.join(htmlize(item) for item in seq)
return '<ul>
<li>' + inner + '</li>
</ul>'
@singledispatch 가 기본 함 수 를 장식 하 였 습 니 다.전문 함수 사용@이렇게 코드 를 작성 하면 Python 은 첫 번 째 매개 변수의 유형 에 따라 해당 하 는 전문 함 수 를 호출 합 니 다.
작은 매듭
본 고 는 먼저 전형 적 인 함수 장식 기 를 소개 했다.장 식 된 함 수 를 새로운 함수 로 바 꾸 고 두 사람 은 똑 같은 매개 변 수 를 받 아들 이 며 장 식 된 함수 가 되 돌아 가 야 할 값 을 되 돌려 주 는 동시에 추가 작업 도 할 것 이다.이 어 장식 기의 두 가지 고급 용법 을 소개 했다.장식 기와 파라미터 화 장식 기 를 중첩 하면 함수 의 내장 등급 을 증가 할 것 이다.마지막 으로 3 개의 표준 라 이브 러 리 의 장식 기 를 소개 합 니 다.기 존 함수 속성 을 유지 하 는 funtools.wraps,캐 시 에 걸 린 함수 결과 의 funtools.lrucache 와 if/elif/elif 코드 를 최적화 한 funtools.singledispatch.
참고 자료:
《유창 한 파 이 썬》https://github.com/fluentpython/example-code/tree/master/07-closure-deco
https://blog.csdn.net/liuzonghao88/article/details/103586634
이상 은 Python 함수 장식 기 고급 용법 의 상세 한 내용 입 니 다.Python 함수 장식 기 용법 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.