66

(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
>>> 

オブジェクトに属性を追加できないのはなぜですか?

4

2 に答える 2

55

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番目の段落を一番上に移動します)。

于 2009-08-16T20:34:10.103 に答える
4

良い質問ですが、これは組み込み/拡張タイプで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__属性の存在と関係があり、より正確にsetattr()は、オブジェクトに属性がない場合に爆発し__dict__ます。

于 2009-08-16T20:39:41.027 に答える