상속이 문제에 더 적합하다는 데 동의합니다.
수업을 꾸미는 데이 질문이 정말 편리하다는 것을 알았습니다. 감사합니다.
상속이 파이썬 2.7 (그리고 원래 함수의 docstring 등을 유지하는 @wraps 등) 에서 어떻게 영향을 받는지를 포함하여 다른 답변을 기반으로 한 또 다른 예가 있습니다 .
def dec(klass):
old_foo = klass.foo
@wraps(klass.foo)
def decorated_foo(self, *args ,**kwargs):
print('@decorator pre %s' % msg)
old_foo(self, *args, **kwargs)
print('@decorator post %s' % msg)
klass.foo = decorated_foo
return klass
@dec # No parentheses
class Foo...
종종 데코레이터에 매개 변수를 추가하려고합니다.
from functools import wraps
def dec(msg='default'):
def decorator(klass):
old_foo = klass.foo
@wraps(klass.foo)
def decorated_foo(self, *args ,**kwargs):
print('@decorator pre %s' % msg)
old_foo(self, *args, **kwargs)
print('@decorator post %s' % msg)
klass.foo = decorated_foo
return klass
return decorator
@dec('foo decorator') # You must add parentheses now, even if they're empty
class Foo(object):
def foo(self, *args, **kwargs):
print('foo.foo()')
@dec('subfoo decorator')
class SubFoo(Foo):
def foo(self, *args, **kwargs):
print('subfoo.foo() pre')
super(SubFoo, self).foo(*args, **kwargs)
print('subfoo.foo() post')
@dec('subsubfoo decorator')
class SubSubFoo(SubFoo):
def foo(self, *args, **kwargs):
print('subsubfoo.foo() pre')
super(SubSubFoo, self).foo(*args, **kwargs)
print('subsubfoo.foo() post')
SubSubFoo().foo()
출력 :
@decorator pre subsubfoo decorator
subsubfoo.foo() pre
@decorator pre subfoo decorator
subfoo.foo() pre
@decorator pre foo decorator
foo.foo()
@decorator post foo decorator
subfoo.foo() post
@decorator post subfoo decorator
subsubfoo.foo() post
@decorator post subsubfoo decorator
나는 그들이 더 간결하다는 것을 알기 때문에 함수 데코레이터를 사용했습니다. 클래스를 장식하는 클래스는 다음과 같습니다.
class Dec(object):
def __init__(self, msg):
self.msg = msg
def __call__(self, klass):
old_foo = klass.foo
msg = self.msg
def decorated_foo(self, *args, **kwargs):
print('@decorator pre %s' % msg)
old_foo(self, *args, **kwargs)
print('@decorator post %s' % msg)
klass.foo = decorated_foo
return klass
괄호를 확인하고 장식 된 클래스에 메소드가없는 경우 작동하는보다 강력한 버전입니다.
from inspect import isclass
def decorate_if(condition, decorator):
return decorator if condition else lambda x: x
def dec(msg):
# Only use if your decorator's first parameter is never a class
assert not isclass(msg)
def decorator(klass):
old_foo = getattr(klass, 'foo', None)
@decorate_if(old_foo, wraps(klass.foo))
def decorated_foo(self, *args ,**kwargs):
print('@decorator pre %s' % msg)
if callable(old_foo):
old_foo(self, *args, **kwargs)
print('@decorator post %s' % msg)
klass.foo = decorated_foo
return klass
return decorator
assert
검사는 장식 괄호없이 사용되지 않았 음. 있는 경우 데코 레이팅되는 클래스 msg
는 데코레이터 의 매개 변수로 전달 되어을 발생 AssertionError
시킵니다.
@decorate_if
decorator
if condition
평가 에만 적용됩니다 True
.
getattr
, callable
테스트 및 @decorate_if
경우 장식이 중단되지 않도록 사용되는 foo()
방법은 클래스가 장식 되에 존재하지 않습니다.