2011-04-21 57 views
9

這工作:屬性分配到內置對象

class MyClass(object): 
    pass 

someinstance = MyClass() 
someinstance.myattribute = 42 
print someinstance.myattribute 
>>> 42 

但這並不:

someinstance = object() 
someinstance.myattribute = 42 
>>> AttributeError: 'object' object has no attribute 'myattribute' 

爲什麼?我有一種感覺,認爲這與對象是一個內置的類有關,但我覺得這不令人滿意,因爲我沒有在MyClass的聲明中改變任何內容。

回答

7

Python將屬性存儲在字典中。您可以將屬性添加到MyClass,看到它有一個__dict__

>>> class MyClass(object): 
>>> pass 
>>> dir(MyClass) 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] 

最重要的區別是,object沒有__dict__屬性。

>>> dir(object) 
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] 

更詳細的解釋:

+1

謝謝!奇怪我沒有找到你發佈這兩個問題的鏈接。 – Turion 2011-04-27 11:27:14

1
>>> type(object) 
type 'type' 
>>> type(MyClass) 
type 'classobj' 

這裏的重要區別是MyClass是一個用戶自定義的類對象。你可以在哪裏修改你的班級。

object()但是是__builtin__類對象。

當您從您的基類以及__builtin__的對象繼承時,您只能修改您定義的新MyClass

0

對於用戶定義的類,在物體上設置一個屬性實際修改屬性的辭典,所以你可以隨時添加新條目。 (Object的__dict__

內置類型的屬性的實現方式不同,不是通用字典,而是直接作爲底層實現的內存佈局。由於字典不存在,並且該類不能在運行時更改,所以不能將新的屬性值添加到內置對象。

請參閱:

http://webcache.googleusercontent.com/search?q=cache:z4to2IGbKDUJ:www.velocityreviews.com/forums/t593269-cant-set-attributes-of-built-in-extension-type.html+setattr+built+in+class&cd=3&hl=en&ct=clnk&gl=us&client=firefox-a&source=www.google.com

http://mail.python.org/pipermail/python-dev/2008-February/077180.html

http://mail.python.org/pipermail/python-list/2010-April/1240731.html

4

至於這樣做的理由,中the BDFL himself的話:

這是被禁止intentionall以防止意外的致命變化 內置類型(致命的部分代碼,你永遠不會通過 )。另外,這樣做是爲了防止這些更改影響駐留在地址空間中的不同 解釋器,因爲內嵌類型 (與用戶定義的類不同)在所有此類解釋器之間共享。