(Python Shell)で記述されています)
>>> 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
>>>
オブジェクトが属性を追加できないのはなぜですか?
object
インスタンスには__dict__
属性がないことに注意してください。
>>> dir(object())
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__']
派生クラスでこの動作を説明する例:
>>> 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
のドキュメントから引用:
[...]
__slots__
宣言は、インスタンス変数のシーケンスを受け取り、各インスタンスに十分なスペースを確保して、各変数の値を保持します。__dict__
はインスタンスごとに作成されないため、スペースが節約されます。
編集:コメントからThomasHに答えるために、OPのテストクラスは「古いスタイル」のクラスです。試してください:
>>> class test: pass
...
>>> getattr(test(), '__dict__')
{}
>>> getattr(object(), '__dict__')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute '__dict__'
__dict__
インスタンスがあることに気付くでしょう。オブジェクトクラスには__slots__
が定義されていない場合がありますが、結果は同じです。__dict__
がないため、属性の動的な割り当てができません。これを明確にするために回答を再編成しました(2番目の段落を先頭に移動します)。
良い質問です。私の推測では、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()
爆発することに関係しています。