2009-10-13 80 views
3

這對我來說似乎有點棘手。前段時間我已經設法用類似的方法覆蓋實例的方法:Python - 爲實例覆蓋__getattribute__?

def my_method(self, attr): 
    pass 

instancemethod = type(self.method_to_overwrite) 
self.method_to_overwrite = instancemethod(my_method, self, self.__class__) 

對我來說工作得很好;但我現在試圖覆蓋實例的__getattribute__()功能,它不適合我的方法似乎是

<type 'method-wrapper'> 

是否有可能辦任何事的原因工作?我在method-wrapper上找不到像樣的Python文檔。

回答

1

我相信方法,包裝大約是用C寫的

3

有幾種方法你不能覆蓋,__getattribute__()就是其中之一。

+2

'__getattribute __()'即使在具有這樣的名稱的屬性時也被調用。你說的對'__getattr __()'方法是真實的。 – 2009-10-13 19:57:03

+1

-1 to Python for'__getattr__','__getattribute__'和'__setattr__'造成的混淆 – 2009-10-13 20:31:03

+0

你是對的;我已經刪除了我的破壞的實現。螞蟻的解決方案是正確的。 – 2009-10-14 07:36:54

5

您希望覆蓋的每個實例的基礎屬性查找算法的方法的包裝?不知道你爲什麼試圖這樣做,我會冒險猜測,有一種更乾淨,更簡單的方式來做你需要做的事情。如果你真的需要那麼就像Aaron說的那樣,你需要在類上安裝一個重定向處理器,因爲Python只在類上查找特殊的方法,而忽略了在實例上定義的任何東西。

你也必須要格外小心,不進入無限遞歸:

class FunkyAttributeLookup(object): 
    def __getattribute__(self, key): 
     try: 
      # Lookup the per instance function via objects attribute lookup 
      # to avoid infinite recursion. 
      getter = object.__getattribute__(self, 'instance_getattribute') 
      return getter(key) 
     except AttributeError: 
      return object.__getattribute__(self, key) 

f = FunkyAttributeLookup() 
f.instance_getattribute = lambda attr: attr.upper() 
print(f.foo) # FOO 

另外,如果你要重寫你的實例方法,你不必實例化的Method對象自己,你可以要麼在生成方法的函數上使用描述符協議,要麼只是咖喱自我參數。

#descriptor protocol 
self.method_to_overwrite = my_method.__get__(self, type(self)) 
# or curry 
from functools import partial 
self.method_to_overwrite = partial(my_method, self) 
+0

不知道「Python只在類上查找特殊方法,忽略實例上定義的任何內容」。謝謝!我沒有得到任何錯誤,但它似乎像Python忽略了我......應該有某種異常提出? IDK ... – JeromeJ 2013-11-12 14:05:56