2011-10-27 13 views
8

通常、あなたが一方のインスタンス属性を文字列に設定することはできませんか?

---------- 
>>> a=A() 
>>> a.foo=42 
>>> a.__dict__ 
{'foo': 42} 
>>> 
---------- 

ために、カスタムオブジェクトに任意の属性を設定することができ、あなたは文字列オブジェクトと同じ結合を行うことはできません。

---------- 
>>> a=str("bar") 
>>> a.foo=42 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'str' object has no attribute 'foo' 
>>> a.__dict__ 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'str' object has no attribute '__dict__' 
>>> 
---------- 

なぜ?

答えて

9

strタイプは、属性dictを持たないタイプです。 the docsから「クラス」セクション:

クラスには、辞書オブジェクトによって実装された名前空間があります。 Class属性の参照は例えば、C.xC.__dict__["x"]

ます。また、カスタムオブジェクトに似た何かを強制することができますに変換され、この 辞書で検索に翻訳されています。一般的には

>>> class X(object): 
...  __slots__=('a',) 
... 
>>> a = X() 
>>> a.a = 2 
>>> a.foo = 2 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'X' object has no attribute 'foo' 

、あなたがすべきではありませんあなたが想定していないオブジェクトのフィールドを設定または変更します。特定のデータ型のドキュメントでは、公開の変更に使用できるフィールドを参照する必要があります。例えば、x座標とy座標のみオブジェクト構造に設定されているReadOnlyPointオブジェクト、

を:

>>> class ReadOnlyPoint(object): 
...  __slots__ = ('_x', '_y') 
...  def __init__(self, x, y): 
...    self._x = x 
...    self._y = y 
...  def getx(self): 
...    return self._x 
...  def gety(self): 
...    return self._y 
...  x = property(getx) 
...  y = property(gety) 
... 
>>> p = ReadOnlyPoint(2, 3) 
>>> print p.x, p.y 
2 3 
>>> p.x = 9 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: can't set attribute 
>>> p._x = 9 
>>> print p.x, p.y 
9 3 

xyプロパティは読み出し専用ている間は、オブジェクトの内部にアクセスするとは変更することができオブジェクトの状態

strオブジェクトに新しいフィールドを追加できないことは、使用しているPythonバージョンに固有の実装の詳細です。

+0

それはstr'型は基本的に不変として設計されて 'という事実の結果ではないですか? 'str'から継承したクラス(私の例のような空のクラス)を作成すると、上記のエラーは発生しません。しかし、タプルの場合は、このエラーが発生します(これらも不変です)。 – Tadeck

+0

@Tadeckまあ、両方の理由が真実に現れます。文字列が組み込まれていて、 '__slots__'を法とするユーザ定義クラスのように、' __dict__'はありません(http://docs.python。 org/py3k/reference/datamodel.html#notes-on-using-slots)を参照してください。また、文字列が不変であるため、属性の割り当てはサポートされません。 OP( "str objectには属性__dict__がありません")の2番目のエラーメッセージにも表示されます。 – delnan

+4

@Tadeckこれは可変性とは関係ありません。 'list'で試してみると、同じ結果が得られます。あなたは基本的なビルトイン型のいずれにもすることはできません – agf

関連する問題