매개변수화된 데커레이터

매일 공부(ML)·2022년 12월 26일
0

Fluent Python

목록 보기
49/130

객체로서의 함수

데커레이터와 클로저

매개변수화된 데커레이터

데커레이터를 파싱할 때 파이썬은 함수를 가져와서 데커레이터 함수의 첫 번째 인수로 넘겨주는데 다른 인수를 받아서 데커레이터를 반환할 수는 없을가요?

답은, 인수를 받아 데커레이터를 반환하는 데커레이터 팩토리를 만들고 나서, 될 함수에 데커레이터 팩토리를 적용하면 됩니다.


매개변수화된 등록 데커레이터

#답에 대한 내용이 어려울 수 있으니 코드로 예시를 듭니다.

registry = []

def register(func):
	print('running register(%s)' % func)
    
    	registry.append(func)
        return func
        
    @register()
    def f1():
    	print('running f1()')
        
        
    print('running main()')
    print('registy ->', registry)
    f1()


@register()
def f2():
	print('running f2()')
    
def f3():
	print('running f3()')

핵심은 register()가 decorate()를 반환하고, 데커레이트될 함수에 decorate()가 적용된다.


import registration_param
registration+param.registry

f2()함수만 registry에 남아 있으므로 register() 데커레이터 팩토리에 activate=False 인수를 전달했으므로 f1()에 적용된 register()를 일반 함수로 사용하려면 괄호문이 필요하고, f()를 registry에 추가하려면 register()(f)로, registry에서 제거하려면 register(activate=False)(f)로 호출해야하므로 괄호 구무을 이용해서 함수를 registry에 추가하거나 제거하는 예를 보여준다.


#나열된 registration_param 모듈 사용

from registration_param import *

registry

register()(f3)

registry

register(active=False)

registry

매개변수화된 데커레이터의 작동 방식은 상담히 복잡함으로 매개변수화된 데커레이터는 일반적으로 데커레이터된 함수를 대체하며 생성하기 위해 함수를 한 단계 더 내포한다.


매개변수화된 clock 데커레이터

#clock_param.py 모듈: 매개변수화된 clock() 데커레이터

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 = func(*_args)
            elapsed = time.time() - t0
            name = func.__name__
            args = ', '.join(repr(arg) for arg in _args)
            result = repr(_result)
            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)
profile
성장을 도울 아카이빙 블로그

0개의 댓글