[英]Why must I explicitly inherit object for slots to work as advertised?
A colleague of mine recently showed me the following session: 我的一位同事最近向我展示了以下会议:
>>> class Foo:
... __slots__ = ['x']
... def __init__(self):
... self.x = "x"
...
>>> f = Foo()
>>> f.x
'x'
>>> f.y = 1
>>> class Bar(object):
... __slots__ = ['x']
... def __init__(self):
... self.x = "x"
...
>>> b = Bar()
>>> b.x
'x'
>>> b.y = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Bar' object has no attribute 'y'
According to the Python documentation , defining __slots__
should make it impossible to assign any other variables than the ones specified in slots, unless the user provides a dict instance manually: 根据Python文档 ,定义
__slots__
应该使得除了用户手动提供dict实例之外,不可能分配除插槽中指定的任何其他变量:
The documentation says nothing about an explicit need to inherit from object
like Bar
does. 文档没有提到像
Bar
那样继承object
的明确需求。
Why does this happen? 为什么会这样?
It does say it, just not very explicitly: 它确实说,只是不明确:
The default can be overridden by defining __slots__ in a new-style class definition.
可以通过在新样式类定义中定义__slots__来覆盖默认值。
In Python 2, when you inherit from object
, you're creating a new-style class. 在Python 2中,当你从
object
继承时,你正在创建一个新式的类。 If you don't, it's an old-style class. 如果你不这样做,那就是一个旧式的课程。
As Jamie pointed out, you want a new-style class. 正如杰米指出的那样,你想要一个新式的课程。 here's why:
这是为什么:
In [5]: import sys
In [6]: sys.getsizeof(f)
Out[6]: 36
In [7]: sys.getsizeof(b)
Out[7]: 28
In [8]: sys.getsizeof(f.__dict__)
Out[8]: 140
In [9]: sys.getsizeof(b.__dict__)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-9-891152de459e> in <module>()
----> 1 sys.getsizeof(b.__dict__)
AttributeError: 'Bar' object has no attribute '__dict__'
In other words, your Foo
class doesn't actually use slots, it still uses __dict__
to store member variables, thus total size of f
is 176 bytes and b
28 bytes (figures for 32-bit arch). 换句话说,你的
Foo
类实际上并没有使用槽,它仍然使用__dict__
来存储成员变量,因此f
总大小是176字节和b
28字节(32位拱的数字)。 It is also why you can assign fy = 1
. 这也是你可以指定
fy = 1
。
Presumably you want __slots__
to reduce memory usage or to force users of your objects to touch only slotted variables. 据推测,您希望
__slots__
减少内存使用量或强制对象的用户只触及插槽变量。 Bar
does both. Bar
做到了。 Foo
does neither. Foo
既没有。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.