我创建了以下类,以一种内存有效的方式存储平面上的可变点 - 我需要一个可变的namedtuple('Point', 'x y')
. 由于实例字典很大,我想我会去__slots__
:
from collections import Sequence
class Point(Sequence):
__slots__ = ('x', 'y')
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __getitem__(self, item):
return getattr(self, self.__slots__[item])
def __setitem__(self, item, value):
return setattr(self, self.__slots__[item], value)
def __repr__(self):
return 'Point(x=%r, y=%r)' % (self.x, self.y)
def __len__(self):
return 2
在 Python 3 上对其进行测试时,一切似乎都很好:
>>> pt = Point(12, 42)
>>> pt[0], pt.y
(12, 42)
>>> pt.x = 5
>>> pt
Point(x=5, y=42)
>>> pt.z = 6
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Point' object has no attribute 'z'
但是在 Python 2 上,z
即使它不在插槽中,我也可以设置属性:
>>> pt = Point(12, 42)
>>> pt.z = 5
>>> pt.z
5
>>> pt.__slots__
('x', 'y')
>>> pt.__dict__
{'z': 5}
为什么会这样,为什么 Python 2 和 Python 3 之间存在差异?