[PYTHON] 내가 추가 한 각 메소드에 대해 반복해서 타이핑하지 않고 클래스의 모든 기능을 어떻게 장식 할 수 있습니까? 파이썬 [복제]
PYTHON내가 추가 한 각 메소드에 대해 반복해서 타이핑하지 않고 클래스의 모든 기능을 어떻게 장식 할 수 있습니까? 파이썬 [복제]
내 클래스에 많은 메소드가 있다고 가정하고 각 메소드에 데코레이터를 적용하고 싶습니다. 나중에 새 메소드를 추가 할 때 동일한 데코레이터를 적용하고 싶지만 메소드 선언 위에 @mydecorator를 모두 쓰려고합니다. 시간?
내가 __call__을 들여다 보면 그게 올바른 길인가?
감사
중요 : 아래 예제는 원래 질문 한 것과 다른 문제를 해결하는 것으로 보입니다.
편집 : ID는이 질문을 나중에 발견, anyobody에 대한 내 문제에 대한 비슷한 솔루션을이 방법으로 표시하려면 같은 의견을 언급 한대로 mixin 사용하십시오.
class WrapinMixin(object):
def __call__(self, hey, you, *args):
print 'entering', hey, you, repr(args)
try:
ret = getattr(self, hey)(you, *args)
return ret
except:
ret = str(e)
raise
finally:
print 'leaving', hey, repr(ret)
그럼 너는 다른
class Wrapmymethodsaround(WrapinMixin):
def __call__:
return super(Wrapmymethodsaround, self).__call__(hey, you, *args)
해결법
-
==============================
1.클래스의 속성을 살펴보고 호출 가능 항목을 꾸미는 함수로 클래스를 꾸미십시오. 호출 할 수있는 클래스 변수가 있고 중첩 클래스 (Sven Marnach가 이것을 가리키는 크레디트)를 꾸미면 일반적으로 오히려 깨끗하고 단순한 솔루션 일 경우 잘못 될 수 있습니다. 예제 구현 (특별한 메소드 (__init__ 등)은 제외되지 않는다.)
클래스의 속성을 살펴보고 호출 가능 항목을 꾸미는 함수로 클래스를 꾸미십시오. 호출 할 수있는 클래스 변수가 있고 중첩 클래스 (Sven Marnach가 이것을 가리키는 크레디트)를 꾸미면 일반적으로 오히려 깨끗하고 단순한 솔루션 일 경우 잘못 될 수 있습니다. 예제 구현 (특별한 메소드 (__init__ 등)은 제외되지 않는다.)
def for_all_methods(decorator): def decorate(cls): for attr in cls.__dict__: # there's propably a better way to do this if callable(getattr(cls, attr)): setattr(cls, attr, decorator(getattr(cls, attr))) return cls return decorate
다음과 같이 사용하십시오.
@for_all_methods(mydecorator) class C(object): def m1(self): pass def m2(self, x): pass ...
파이썬 3.0과 3.1에서는 호출 가능 함수가 존재하지 않습니다. 그것은 Python 2.x에서 영원히 존재했으며 Python 3.2에서 isinstance (x, collections.Callable)의 래퍼로 돌아 왔습니다. 따라서이 버전에서이 클래스를 사용할 수 있습니다 (또는 이것을 사용하여 자신 만의 호출 가능 대체를 정의 할 수 있습니다).
-
==============================
2.명시 적 접근이 가능할 때 나는 마법적인 접근 방식을 선호하지 않지만, 아마도 이것을 위해 메타 클래스를 사용할 수 있습니다.
명시 적 접근이 가능할 때 나는 마법적인 접근 방식을 선호하지 않지만, 아마도 이것을 위해 메타 클래스를 사용할 수 있습니다.
def myDecorator(fn): fn.foo = 'bar' return fn class myMetaClass(type): def __new__(cls, name, bases, local): for attr in local: value = local[attr] if callable(value): local[attr] = myDecorator(value) return type.__new__(cls, name, bases, local) class myClass(object): __metaclass__ = myMetaClass def baz(self): print self.baz.foo
myClass의 각 호출 가능 객체가 myDecorator로 꾸며져있는 것처럼 작동합니다.
>>> quux = myClass() >>> quux.baz() bar
-
==============================
3.죽은자를 살리기 위해서가 아니라, 나는 정말로 델의 대답을 좋아했지만, 그것이 부족하다는 것을 알았다.
죽은자를 살리기 위해서가 아니라, 나는 정말로 델의 대답을 좋아했지만, 그것이 부족하다는 것을 알았다.
def for_all_methods(exclude, decorator): def decorate(cls): for attr in cls.__dict__: if callable(getattr(cls, attr)) and attr not in exclude: setattr(cls, attr, decorator(getattr(cls, attr))) return cls return decorate
편집 : 들여 쓰기 수정
그래서 당신은 메소드 // 속성 // 당신이 장식하고 싶지 않은 것들을 지정할 수 있습니다.
-
==============================
4.위의 답 중 아무 것도 __dict__를 사용하여 수행하지 않은 상속 된 메서드를 꾸미려고했기 때문에 나에게 도움이되지 않았으며 메타 클래스로 작업을 복잡하게 만들지 않았습니다. 마지막으로, 클래스의 모든 함수에서 사용되는 시간을 측정하기위한 프로파일 링 코드를 추가해야 할 필요가 있기 때문에 Python 2에 대한 해결책이있는 것이 좋습니다.
위의 답 중 아무 것도 __dict__를 사용하여 수행하지 않은 상속 된 메서드를 꾸미려고했기 때문에 나에게 도움이되지 않았으며 메타 클래스로 작업을 복잡하게 만들지 않았습니다. 마지막으로, 클래스의 모든 함수에서 사용되는 시간을 측정하기위한 프로파일 링 코드를 추가해야 할 필요가 있기 때문에 Python 2에 대한 해결책이있는 것이 좋습니다.
import inspect def for_all_methods(decorator): def decorate(cls): for name, fn in inspect.getmembers(cls, inspect.ismethod): setattr(cls, name, decorator(fn)) return cls return decorate
출처 (약간 다른 해결책) : https://stackoverflow.com/a/3467879/1243926 거기에서 파이썬 3을 위해 그것을 어떻게 바꾸는 지 볼 수 있습니다.
다른 답변에 대한 의견을 제안 할 때 inspect.getmembers (cls, inspect.isroutine)를 대신 사용해보십시오. 파이썬 2와 파이썬 3 모두에서 작동하고 상속 된 메소드를 장식하는 적절한 솔루션을 찾았다면 여전히 7 줄에서 수행 할 수 있습니다.
-
==============================
5.당신은 메타 클래스를 생성 할 수 있습니다. 상속 된 메서드를 장식하지 않습니다.
당신은 메타 클래스를 생성 할 수 있습니다. 상속 된 메서드를 장식하지 않습니다.
def decorating_meta(decorator): class DecoratingMetaclass(type): def __new__(self, class_name, bases, namespace): for key, value in list(namespace.items()): if callable(value): namespace[key] = decorator(value) return type.__new__(self, class_name, bases, namespace) return DecoratingMetaclass
이렇게하면 지정된 함수로 모든 메소드를 꾸미는 메타 클래스가 생성됩니다. 다음과 같이 Python 2 또는 3에서 사용할 수 있습니다.
def doubling_decorator(f): def decorated(*a, **kw): return f(*a, **kw) * 2 return decorated class Foo(dict): __metaclass__ = decorating_meta(doubling_decorator) def lookup(self, key): return self[key] d = Foo() d["bar"] = 5 print(d.lookup("bar")) # prints 10
from https://stackoverflow.com/questions/6307761/how-can-i-decorate-all-functions-of-a-class-without-typing-it-over-and-over-for by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 장고 템플릿 내에서 인덱스별로 목록 항목을 참조 하시겠습니까? (0) | 2018.10.11 |
---|---|
[PYTHON] 수레의 경우 range () (0) | 2018.10.11 |
[PYTHON] 커스텀 비교 술어를 가진 heapq (0) | 2018.10.11 |
[PYTHON] 파이썬 setuptools로 설치 후 스크립트 (0) | 2018.10.11 |
[PYTHON] 교대로 두 목록을 결합하는 Pythonic 방식? (0) | 2018.10.11 |