2013-10-30 61 views
3

我有一個對象,其主要價值在於將給定的裝飾器應用於從超類繼承的每個函數並提供它的單獨版本。僅供參考裝飾低於:定義函數存根enmasse

def hierarchywrapper(func): 
    def wrapper(self, *args, **kwargs): 
     for key, value in self.hierarchy.items(): 
      try: 
       result = getattr(value, func.__name__)(*args, **kwargs) 
       if result and len(result): 
        return result 
       else: 
        pass 
      except: 
       pass 
     return None 
    return wrapper 

超類包含這個裝飾對象的有相當多的功能,我寧願不寫出來,爲他們每個人的存根。正如你所看到的,這些功能的內容並不是非常重要,只是真的需要存根。

是否有某種方法來定義函數樁?或者,有什麼方法可以表明我只是想將這個裝飾器應用於每個繼承的函數?要做到這一點

+1

我不確定這是否可行,但是您可以使用自定義的__getattr__方法來捕獲不存在的函數調用嗎? – GWW

+0

@GWW嗯......我不太確定,如果我抓住你的漂移。你能提供某種例子嗎? –

+0

@SlaterTyranus請參閱:http://stackoverflow.com/a/2704528/1726343。 –

回答

2

一種方法是專門的__getattribute__方法在子類:

def __getattribute__(self, name): 
    attr = super(MySuperclass, self).__getattribute__(name) 
    if callable(attr): 
     return hierarchywrapper(attr) 
    else: 
     return attr 

@eevee通過包裝父對象,而不是繼承它表明一個更通用的方法:

class CallableHierarchyWrapper(object): 

    def __init__(self, wrapped_object): 
     self.wrapped_object = wrapped_object 

    def __getattribute__(self, name): 
     attr = self.wrapped_object.__getattribute__(name) 
     if callable(attr): 
      return hierarchywrapper(attr) 
     else: 
      return attr 
+0

Oooh。我懂了!偉大的解決方案,正是我所期待的。 –

+0

更好的是,包裝而不是子類化,這將適用於任何類:)還要注意,特殊的方法不會觸發'__getattribute__'。 – Eevee

+1

@eevee - 你會包裝什麼?我並不是不同意,我只是不確定你會怎麼做。 –