无法将属性设置为字符串?

时间:2011-10-27 01:25:24

标签: python

通常,您可以为自定义对象设置任意属性,例如

----------
>>> 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__'
>>>
----------

为什么?

2 个答案:

答案 0 :(得分:10)

因为str类型是一种没有属性dict的类型。来自the docs,“类”部分:

  

类具有由字典对象实现的命名空间。   类属性引用在此转换为查找   字典,例如,C.x被翻译为C.__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'

通常,您不应该设置或修改您不应该使用的对象字段。特定数据类型的文档应该引用可用于 public 修改的字段。

例如,ReadOnlyPoint对象,其中x和y坐标仅在对象构造上设置:

>>> 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版本。

答案 1 :(得分:2)

http://docs.python.org/reference/datamodel.html

  

如果班级有 setattr ()或 delattr ()方法,这是   调用而不是直接更新实例字典。

http://docs.python.org/reference/datamodel.html#object.setattr