2014-07-25 21 views
2
class B(object): 
"""new style class""" 

    def __getattribute__(self, name): 
     print '__getattribute__ called' 
     return super(B, self).__getattribute__(name) 

    def __getattr__(self, name): 
     print '__getattr__ called' 

    def __setattr__(self, name, value): 
     print '__setattr__ called' 
     if name in ['forbid', 'refuse']: 
      raise AttributeError('Attribute name invalid!') 
     else: 
      return super(B, self).__setattr__(name, value) 

B級定義爲上面,然後我試着做一下__getattr__,__getattribute__一些測試:如何解釋關於__getattribute__,__getattr__的'怪異'結果?

b = B() 
setattr(b, 'test', 100) 

print b.__dict__ 
print b.__getattribute__('__dict__') 
print b.__getattr__('__dict__') 
print getattr(b, '__dict__') 

最後的結果是,:

__getattribute__ called 
{'test': 100} 
__getattribute__ called 
__getattribute__ called 
{'test': 100} 
__getattribute__ called 
__getattr__ called 
None 
__getattribute__ called 
{'test': 100} 

來到這裏,我的問題:

1. print b.__getattribute__('__dict__')兩次調用__getattribute__,爲什麼?

2. print b.__getattr__('__dict__')先調用__getattribute__然後再調用__getattr__下一個?爲什麼返回無?

上面的結果對我來說似乎很奇怪,我真的不明白這些方法是如何工作的。任何建議或建議,我都讚賞。謝謝!

+0

對於Q2,'__getattr__'負責'返回None';它是所有'打印'。 – jonrsharpe

+0

對於Q1,調用'__getattribute__'來解析'__getattribute__'! – jonrsharpe

+0

@jonrsharpe Q 2,在調用'__getattr__'之前,已調用__getattribute__','__getattribute__'的'return'在哪裏?我需要知道這些方法是如何工作的,如果你能明白,謝謝:) – LeoTao

回答

3
  1. ,當你做b.__getattribute__第一__getattribute__調用完成。你想獲得叫做__getattribute__的屬性(是的,我知道這聽起來很不錯)。當您請求稱爲__getattribute__的屬性時,將調用__getattribute__,您會得到結果中的__getattribute__方法。然後你只需調用__getattribute__方法 - 這裏有__getattribute__

  2. b.__getattr__電話__getattribute__獲得屬性,叫做__getattr__(是的,我知道)第二個電話。你得到__getattr__方法作爲回報。然後你打電話給__getattr__方法。它不會顯式返回任何內容,這意味着它隱式地返回None。

下面是當你看到some_obj_of_class_B.some_method()會發生什麼的簡化版本:

  • __getattribute__被調用來獲取屬性稱爲some_method__getattribute__打印'我被叫了!'並委託其工作,object.__getattribute__(我想這,檢查some_obj_of_class_B的__dict__,檢查其類__dict__,基類__dict__,處理描述符等希望object.__getattribute__回報some_method(這是希望的功能或者更精確地綁定方法)
  • 。此功能/綁定的方法被稱爲在你的情況綁定方法是__getattribute__本身這就是爲什麼它叫了兩聲
+0

好的解釋!我知道了:) @Nigel Tufnel – LeoTao

+0

根據我上面的評論,例如, 'b .__ getattribute __()'是'b .__ getattribute __(「__ getattribute __」)()' – jonrsharpe