向python对象添加属性

2022-01-13 00:00:00 python object attributes

问题描述

这件事困扰了我一段时间.为什么我做不到:

It's a thing that bugged me for a while. Why can't I do:

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

...虽然我可以做到以下几点?

...while I can do the following?

>>> class Bar():
...     pass
... 
>>> a = Bar()
>>> a.foo = 10 #ok!

这里的规则是什么?你能指点我一些描述吗?

What's the rule here? Could you please point me to some description?


解决方案

您可以为任何具有 __dict__ 的对象添加属性.

You can add attributes to any object that has a __dict__.

  • x = object() 没有它,例如.
  • 字符串和其他简单的内置对象也没有.
  • 使用 __slots__ 的类也没有.
  • class 定义的类有它,除非前面的语句适用.
  • x = object() doesn't have it, for example.
  • Strings and other simple builtin objects also don't have it.
  • Classes using __slots__ also do not have it.
  • Classes defined with class have it unless the previous statement applies.

如果一个对象使用 __slots__/没有 __dict__,通常是为了节省空间.例如,在 str 中,使用 dict 就太过分了——想象一下非常短的字符串会产生多大的膨胀.

If an object is using __slots__ / doesn't have a __dict__, it's usually to save space. For example, in a str it would be overkill to have a dict - imagine the amount of bloat for a very short string.

如果要测试给定对象是否有 __dict__,可以使用 hasattr(obj, '__dict__').

If you want to test if a given object has a __dict__, you can use hasattr(obj, '__dict__').

这也可能很有趣:

某些对象,例如内置类型及其实例(列表、元组等)没有 __dict__.因此无法在它们上设置用户定义的属性.

Some objects, such as built-in types and their instances (lists, tuples, etc.) do not have a __dict__. Consequently user-defined attributes cannot be set on them.

另一篇关于Python的数据模型包括__dict____slots__等有趣的文章是this 来自 python 参考.

Another interesting article about Python's data model including __dict__, __slots__, etc. is this from the python reference.

相关文章