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も使えそうだ。
- BOM付きUTF-8からBOMを除去するpython
- jythonのヒープメモリ設定
- Kotlin1.2.50がリリースされていた
- macOSをHigh Sierraに更新した。スクリプト実行環境のバージョンは変わったのか
- macOSをMojaveに更新した。スクリプト実行環境のバージョンは変わったか
- pathlib.Pathを調べる
- pyenvでpython環境をインストール
- pyenvとvirtualenvでpython環境を構築
- python unpack
- python3で数値のlistを文字列のlistに変換