Pythonでデータクラス。その後。

Pythonでデータクラス。その後。

Python3.6でデータクラスの使用方法を知ってから、typing.NamedTupleを使ってPythonツールを作ってきた。しかし、今更ながらPython2.7(Jython)のツールを作る必要がでてきた。データクラスが使えない。
と思って、ドキュメントを見ていたら、collections.namedtupleはPython2.6から使えた。じゃあ、これを使えばいいか。

collections.namedtuple

1
2
3
4
5
from collections import namedtuple

Point = namedtuple('Point', 'x,y')
pos = Point(10, 20)
print(pos)

便利だ。__init__や__str__、__repr__まで実装されている。
それにVisual Studio Codeがプロパティを認識してくれている。

しかしtupleなので、プロパティの変更ができない。

1
2
3
4
>>> pos.x = 15
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

けど方法がないわけではない。

_replace

1
2
pos = pos._replace(x=15)
print(pos)

tupleなので変更はできない。しかし、プロパティを変更した新しいtupleを返してくれる。
これで、プロパティの変更のようなことができた。

namedtupleはクラスだ。したがって継承できる。
初期値として渡すような項目はnamedtupleとして定義し、変更する必要があったり、後から設定するようなプロパティは、そのnamedtupleを継承したクラスの方で定義してもよい。

namedtupleの継承(拡張)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from collections import namedtuple

Point = namedtuple('Point', 'x,y')
class MyPoint(Point):
    z = 0

    def move_z(self):
        self.z += 1

    def __str__(self):
        return 'X:{} Y:{} Z:{}'.format(
            self.x, self.y, self.z)

pos = MyPoint(10, 20)
pos.z = 30
pos.move_z()
print(pos)

これで不足ないデータクラスが作成できた。
この例では__str__を書き換えているが、本当は__repr__も書き換えておかないといけない。
__repr__を書き換えるなら、__init__も書き換える必要があるが・・・

まとめ

Python2.7でも、ここまでできるとは。
まだまだJythonも使えそうだ。

同じタグの記事
同じカテゴリの記事

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA