2012-03-04 110 views
1
>>> dir(classAInstance.objectTInstance.__dict__) 
    ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', 
'__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', 
'__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__setitem__', '__str__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 
'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] 

>>> classAInstance.objectTInstance.attB    # Access Method 1 
199 

>>> classAInstance.objectTInstance.__dict__['attB'] # Access Method 2 
199 

>>> classAInstance.objectTInstance['attB']   # Access Method 3 
Traceback (most recent call last): 
    File "<input>", line 1, in ? 
AttributeError: ObjectT instance has no attribute '__getitem__' 

要求:classAInstanceClassAobjectTInstance一個insance是ObjectT一個實例。AttributeError的:ObjectT實例沒有屬性 '__getitem__'

問題>classAInstance.objectTInstance存儲屬性attB? 爲什麼訪問方法3不起作用? __dict__究竟存儲什麼?

object.__dict__ 
    A dictionary or other mapping object used to store an object’s (writable) attributes. 

基於我的理解,Access方法1和2完全相同。 attB也存儲在ObjectT的對象的__dict__中。爲了使Access 3能夠工作,ObjectT必須提供名爲__getitem__的字典魔術功能。

這是正確的嗎?

謝謝

回答

3

當通過您嘗試的第一個方法訪問的屬性,Python中首先檢查__dict__以查看是否屬性是在那裏。如果是,那就是它的用途。然後它檢查對象的__class____dict__。如果仍然沒有找到,它會繼續搜索超類。 (如果涉及多重繼承,則會變得更復雜。)如果仍未找到,則它會查找該類或任何超類的__getattr__以及用於獲取該屬性的調用。如果所有這些都失敗了,那就錯了。

第二種方法直接訪問對象的__dict__。它不會像第一個那樣檢查班級的屬性或撥打__getattr__

第三種方法是完全別的東西;它會嘗試撥打__getitem__(不要將其與__getattr__混淆)。

1

您的困惑之處在於您有一個字典對象,該對象的__dict__屬性也指向字典。 您的對象和它的__dict__屬性不是相同的字典。

大多數Python對象有一個__dict__屬性,用於存儲對象的屬性;這些屬性可以使用.語法(它搜索對象的__dict__以及它的類及其派生類)進行訪問。當您的對象字典時,它本身還存儲項目這些使用[...]語法進行訪問。

可以在dict子類中編寫__getattr__()__setattr__()方法,允許字典中的項目也可以使用點符號,JavaScript語言來訪問。這通常是一個壞主意,因爲Python程序員不希望Python像JavaScript一樣行事。

相關問題