2009-08-16 11 views
53

なぜPythonでオブジェクトに属性を追加できないのですか? (Pythonのシェルで書かれた)

>>> o = object() 
>>> o.test = 1 

Traceback (most recent call last): 
    File "<pyshell#45>", line 1, in <module> 
    o.test = 1 
AttributeError: 'object' object has no attribute 'test' 
>>> class test1: 
    pass 

>>> t = test1() 
>>> t.test 

Traceback (most recent call last): 
    File "<pyshell#50>", line 1, in <module> 
    t.test 
AttributeError: test1 instance has no attribute 'test' 
>>> t.test = 1 
>>> t.test 
1 
>>> class test2(object): 
    pass 

>>> t = test2() 
>>> t.test = 1 
>>> t.test 
1 
>>> 

なぜあなたはそれに属性を追加することを可能に反対しないのですか?

答えて

38

objectインスタンスがノー__dict__属性があることに注意:派生クラスでこの現象を説明する

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

例:

slots上のドキュメントから引用
>>> class Foo(object): 
...  __slots__ = {} 
... 
>>> f = Foo() 
>>> f.bar = 42 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'Foo' object has no attribute 'bar' 

[...] __slots__の宣言takeインスタンス変数のシーケンスを保持し、各インスタンスに各変数の値を保持するのに十分なスペースを確保します。 __dict__がインスタンスごとに作成されないため、領域が節約されます。

EDIT:コメントからThomasHに答えるために、OPのテストクラスは「古いスタイル」のクラスです。試してみてください:

__dict__インスタンスがあります。オブジェクトクラスには__slots__が定義されていない可能性がありますが、結果は同じです:__dict__の欠如。属性の動的割り当てを妨げるものです。私はこれをより明確にするために私の答えを再編成しました(第2段落を上に移動)。

+2

インスタンスメンバーの割り当てを防止するために、* object *クラスが\ _ \ _ slots \ _ \ _を使用していると言っています。これは前提か事実ですか(つまり、* object *の実装にありますか)? *オブジェクト*インスタンスからの\ _ \ dict \ _ \ _の単なる不在は、指標ではないからです。 OPの* test1 *クラスのインスタンスは、dir()で呼び出されたときに\ _ \ _ dict \ _ \ _と同じ欠落を示しますが、インスタンスメンバーの割り当ては可能です。 – ThomasH

+1

@ThomasH、私が答えに加えたノートを見てください。 – ars

3

良い質問ですが、これはobject内蔵/拡張タイプであるということと関連があります。

>>> class test(object): 
... pass 
... 
>>> test.test = 1 
>>> object.test = 1 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: can't set attributes of built-in/extension type 'object' 

IIRC、これは、より正確__dict__属性や、オブジェクトが__dict__属性を持っていないときsetattr()が吹いの存在に関係しています。

関連する問題