如果一切都是对象,为什么我不能为某些人添加属性?

时间:2016-03-22 06:05:14

标签: python attributes

如果一切都是对象,那么为什么以下代码无法工作:

x = 6
x.newAttrib = 8

所以它不是一个对象,或一些有限的对象?

1 个答案:

答案 0 :(得分:9)

是的,一切都是对象。但是,作为对象的一切都意味着一切都需要任意属性。

Python中的整数是对象,并且具有属性和方法(只是 callable 属性):

>>> x = 6
>>> x.real
6
>>> x.imag
0
>>> x.bit_length()
3

要支持任意属性,对象需要具有__dict__映射。整数没有这样的映射:

>>> x.__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__dict__'

其他对象与函数一样,例如:

>>> def foo(): pass
...
>>> foo.__dict__
{}
>>> foo.bar = 'baz'

__dict__映射需要付出代价:此类对象的内存占用量更大。由于Python使用 lot 整数,因此为它们提供__dict__映射是有意义的,以节省内存。你很少无论如何都需要给他们额外的属性。

您可以通过为您的班级__slots__ class variable定义您自己的类来生成没有__dict__属性的实例;这定义了实例支持的固定属性。这样可以节省相同的内存:

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

反之亦然,如果您创建了int的子类而没有为您的子类提供__slots__变量,则可以向该子类添加任意属性:

>>> class MyInt(int):
...     pass
...
>>> mi = MyInt(6)
>>> mi.foo = 'bar'