向Python对象添加属性
这让我困惑了一段时间。为什么我不能这样做:
>>> a = ""
>>> a.foo = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'foo'
...而我却可以这样做呢?
>>> class Bar():
... pass
...
>>> a = Bar()
>>> a.foo = 10 #ok!
这里面有什么规则吗?能不能给我指个方向,告诉我哪里有相关的说明?
1 个回答
60
你可以给任何有 __dict__
的对象添加属性。
- 比如,
x = object()
这个对象就没有这个功能。 - 字符串和其他一些简单的内置对象也没有这个功能。
- 使用
__slots__
的类同样没有这个功能。 - 用
class
定义的类一般都有这个功能,除非上面提到的情况适用。
如果一个对象使用了 __slots__
或者没有 __dict__
,通常是为了节省空间。比如,对于一个 str
类型的对象来说,使用字典会显得太浪费了——想象一下,如果是一个非常短的字符串,使用字典会造成多大的冗余。
如果你想检查一个对象是否有 __dict__
,可以用 hasattr(obj, '__dict__')
来测试。
这篇文章也许会让你感兴趣:
一些对象,比如内置类型及其实例(如列表、元组等),是没有
__dict__
的。因此,用户自定义的属性不能在这些对象上设置。
关于Python数据模型的另一篇有趣的文章,包括 __dict__
、__slots__
等内容,可以参考 这篇来自Python官方文档的文章。