2014-01-07 3 views
0

함수에 전달 된 인수 유형을 확인하는 데코레이터 메소드가 있습니다. 난 그냥 WHATTOPUTHERE의 장소에 ClassA을 넣을 수 있습니다 다른 클래스에서데코레이터 함수에 현재 클래스 전달

class ClassA: 
    @accepts(WHATTOPUTHERE) 
    def doSomething(otherObject): 
     # Do something 

: 클래스에서 지금

def accepts(*types): 
    def check_accepts(f): 
     assert len(types) == f.func_code.co_argcount 
     def new_f(*args, **kwds): 
      for (a, t) in zip(args, types): 
       assert isinstance(a, t), \ 
         "arg %r does not match %s" % (a,t) 
      return f(*args, **kwds) 
     new_f.func_name = f.func_name 
     return new_f 
    return check_accepts 

은 (classA.py에), 나는 방법은 동일한 클래스의 인수를 허용하려면 그러나 classA.py 안에, ClassA는 알려져 있지 않습니다. 어떻게 현재 클래스를 @accepts() 함수에 전달할 수 있습니까?

+0

죄송합니다, 나는 그 뜻을 모르겠습니다. 그건 내 의도가 아니야. 왜 그렇게 될지 설명해 주시겠습니까? – RemiX

+0

Hrm, 생각 해보니, 여기서 일어날 일은 없을거야. 파이썬 2에서 * 이미 * 수행 한 것과 같은 타입 체크를 다시 구현했다. 'self'가 현재 클래스의 동일한 유형 또는 하위 클래스가되도록합니다. 그러나 여기에서는'args [0]'이''self ''라는 것을 고려하지 않은 것처럼 보입니다. –

답변

1

데코레이터의 기능 기반 버전을 사용하고 클래스 정의 후 적용 :

class ClassA: 
    def doSomething(otherObject): 
     # Do something 
ClassA.doSomething = accepts(ClassA)(ClassA.doSomething) 

또 다른 방법은 자동으로 클래스를 생성 한 후이를 적용 할 것이라고 Metaclass 쓰기 될 것이다 :

class Meta(type): 

    def __new__(cls, clsname, bases, dct): 
     fields = ('doSomething',) #Fields on which you want to apply the decorator 
     for name, val in dct.items(): 
      if name in fields: 
       dct[name] = accepts(cls)(val) 
     return type.__new__(cls, clsname, bases, dct) 


class ClassA(object): 
    __metaclass__ = Meta 
    def doSomething(otherObject): 
     pass 

new_f.func_name = f.func_name과 같은 수동 작업 대신 functools.wraps을 사용하십시오. 이것은 문서 문자열, 인수 목록 등을 보존 할 것입니다.

from functools import wraps 
def accepts(*types): 
    def check_accepts(f): 
     print "inside" 
     assert len(types) == f.func_code.co_argcount 
     @wraps(f) 
     def new_f(*args, **kwds): 
+0

완벽하게 작동합니다. 감사합니다. – RemiX