2014-09-18 35 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 2014-09-18 20:27:21

+0

@chepner:同時遍歷基類和超類迭代器。 – 2014-09-18 20:28:35

+1

我只是將這個添加爲您之前關於定義方法的類的問題的用例(剛注意到您發佈了這兩個方法),而不是單獨在這裏詢問。 – chepner 2014-09-18 20:33:08

回答

-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',等等,直到你遇到遞歸錯誤。 (這與Blckknight上個月在rioppi現在刪除的答案中指出的問題實際上是相同的問題。) – abarnert 2014-10-23 22:24:25

+0

啊,對......沒有想到通過。我是否應該將我的答覆作爲一個不好的例子? – greschd 2014-10-25 17:56:18