メモリ効率の良い方法で変更可能なポイントを平面に格納するために、次のクラスを作成しました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 の違いはなぜですか?