2014-09-18 3 views
1

???은 어떻게 작성합니까?Python 3의 메소드 데코레이터에서 super를 어떻게 호출합니까?

def ensure_finished(iterator): 
    try: 
     next(iterator) 
    except StopIteration: 
     return 
    else: 
     raise RuntimeError 


def derived_generator(method): 
    def new_method(self, *args, **kwargs): 
     x = method(self, *args, **kwargs) 
     y = getattr(super(???, self), method.__name__)\ 
      (*args, **kwargs) 

     for a, b in zip(x, y): 
      assert a is None and b is None 
      yield 

     ensure_finished(x) 
     ensure_finished(y) 

    return new_method 
+2

이 무엇을 달성하기 위해 거기에 있어야한다? – chepner

+0

@chepner : 기본 반복자와 수퍼 클래스 반복자를 동시에 반복합니다. –

+1

여기에 별도로 질문하는 것이 아니라 메소드를 정의하는 클래스에 관한 이전 질문에 대한 유스 케이스로 추가합니다 (방금 두 가지를 게시 한 것으로 나타났습니다). – chepner

답변

-1

편집 :이 코멘트에 언급 된 이유로 작동하지 않습니다. 나는 대답을하려고하는 다음 사람이 똑같은 일을하지 않도록 (실제 답변이 나타날 때까지) 여기에 남겨 둘 것입니다.

당신은 내가 당신의 코드를 약간 단순화 type(self)

를 사용해야하지만, 본질은 여전히 ​​

def derived_generator(method): 
    def new_method(self, *args, **kwargs): 
     x = method(self, *args, **kwargs) 
     y = getattr(super(type(self), self), method.__name__)\ 
      (*args, **kwargs) 

     for a, b in zip(y, x): 
      yield a, b 

    return new_method 

class BaseClass(object): 
    def iterator(self): 
     return [1, 2, 3] 

class ChildClass(BaseClass): 
    @derived_generator 
    def iterator(self): 
     return [4, 5, 6] 

a = ChildClass() 
for x in a.iterator(): 
    print(x) 
+2

하위 클래스의 인스턴스에서이 메서드를 호출하지 않을 경우에만 작동합니다. 예를 들어'GrandchildClass'를 만들고 거기에'@ derived_generator'를 추가한다고 상상해보십시오. 그래서'GrandchildClass.iterator'는'ChildClass.iterator'에 비해 더 좋을 것이고, 재귀 오류를 치기 전까지는'ChildClass.iterator'를 다시 능가 할 것입니다. (이것은 Blockknight가 지난 달에 리오피가 지금 삭제 한 대답에서 지적한 것과 실질적으로 동일한 문제입니다.) – abarnert

+0

아, 맞아 ... 그걸 생각하지 않았어. 답장을 나쁜 예로 남겨 두어야합니까? – greschd

관련 문제