2012-10-17 4 views
2

함수에 적용 할 때 선택적 구성을 허용하는 데코레이터를 제공하고자합니다.Python의 사용자 정의 가능한 장식 자

간단한 구현은 다음과 같습니다

import functools 


class Deco(object): 
    config = {'message': 'hello'} 

    def __init__(self, func): 
     self.func = func 
     functools.wraps(func)(self) 

    def __call__(self, *args, **kwargs): 
     print self.config['message'] 
     return self.func(*args, **kwargs) 

    @classmethod 
    def customize(cls, **kwargs): 
     """Return a customized instance of this class. """ 
     return type(cls.__name__, (Deco,), {'config': kwargs}) 


@Deco 
def add(a, b): 
    return a + b 


@Deco.customize(message='bye') 
def sub(a, b): 
    return a - b 


>>> add(1, 2) 
'hello' 
>>> sub(2, 1) 
'bye' 

내가 장고보기위한 사용자 친화적 인 장식을 제공하기 위해 그것을 사용하고 싶습니다.

이 접근 방식은 오류없이 작동하지만 클래스가 자신의 사용자 정의 된 인스턴스를 데코레이터로 인스턴스화하는 정적 팩토리 메소드를 가질 수 있도록 허용하는 데 나쁜 점이 있습니까?

+4

작동합니까? 그렇지 않은 경우 어떤 오류가 발생합니까? –

+0

가끔 난독 화해서는 안되는 것들을 난독 화하지만 ... 그걸로 네가 잘하는 한 내가 너의 좋은 생각이야 ... –

답변

2

데코레이터를 사용할 때마다 여분의 하위 클래스를 만들지 않고 작업 할 수 있지만 코드는 괜찮습니다. 현명한 당신이 기능의 수천 적어도 수백 장식 될하지 않는 한 (코드에 차이가 없을 것 성능 동안,

class Deco(object): 
    config = {'message': 'hello'} 

    def __init__(self, func=None, **kwargs): 
     if kwargs: 
      self.config = kwargs 
     if func is not None: 
      self._decorate(func) 

    def _decorate(self, func): 
     self.func = func 
     functools.wraps(func)(self) 

    def __call__(self, *args, **kwargs): 
     if not hasattr(self, "func"): 
      self._decorate(func) 
      return self 
     print self.config['message'] 
     return self.func(*args, **kwargs) 

그래서 - 코드가 추가 객체를 생성 : 별도의 서브 클래스가없는 방법을 따라 뭔가를 할 수 - 클래스 - 데코레이터가 사용될 때마다, 그 클래스의 인스턴스 외에도) - 사람들에게 영향을주는 것은 (모듈을 사용하거나 완료 한 후에 그것을 유지하기 위해) 코드를 검토하는 것입니다. 동적으로 생성하는 데코레이터가 너무 진보되어 사람들을 겁 먹게 할 수도 있습니다. 위의 제 제안만큼 간단하지만 파이썬에서 클래스 생성 메커니즘을 이해합니다.

관련 문제