无法将属性设置为字符串吗?
通常情况下,你可以给自定义对象设置任意属性,比如:
----------
>>> 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 个回答
2
http://docs.python.org/reference/datamodel.html
如果一个类里面有 setattr() 或 delattr() 这两个方法,那么在更新这个类的实例字典时,就会调用这两个方法,而不是直接修改字典。
http://docs.python.org/reference/datamodel.html#object.setattr
11
因为 str
类型是一个没有字典属性的类型。从文档的“类”部分可以看到:
一个类有一个由字典对象实现的命名空间。类属性的引用会被转换成在这个字典中的查找,比如
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'
一般来说,你不应该设置或修改那些不应该被修改的对象字段。具体数据类型的文档会告诉你哪些字段可以被公开修改。
举个例子,有一个 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
虽然 x
和 y
属性是只读的,但访问对象内部可以让你改变对象的状态。
不能给 str
对象添加新字段是一个实现细节,这与您使用的 Python 版本有关。