fieldenum: PythonでRust風のフィールド付きenumをサポート
(github.com/ilotoki0804)- fieldenumは値を持つ(インスタンス化できる)enumです。
- Rustのフィールド付きenumをきれいにサポートします。
- 関数型プログラミングの純粋性とPythonにおける実用性のあいだで、バランスを取ることを目指しました。
- デフォルトで、
Noneの代替となるOptionや、例外の代替となるBoundResultをサポートしています。 - 完全にテストされています。
- まだ英語ドキュメントは手薄ですが、今後少しずつ充実させていく予定です。
- Issue、PR、star など、さまざまな形での支援を歓迎します。
14件のコメント
dataclassの union 型のほうがより良いのでは、と思うのですが、宣言文が短いこと以外にはあまり利点が分かりません。fieldenumに特別に優れている点はあるのでしょうか?宣言が短く簡潔で、必要な部分だけがあることも大きな利点です。
たとえば、
上の fieldenum を dataclass で実装しようとすると、次のように書かなければなりません。
コードは長くなって見づらくなり、ミスをする可能性も高くなりますし、コードがきれいだとは感じにくいですよね。
もちろん、このように書いたとしても fieldenum が提供するさらに多くの機能(ジェネリクス、repr、
__fields__など)は利用できません。したがって、これらすべてを実装してまとめた fieldenum があれば、はるかに便利です。
そのほかにも、
例パートの内容も参考になると思います。それでも、class 定義に必要なボイラープレートコードがない点や、enum と class をひとつのインターフェースとして使える点は利点になりそうですね。詳しい説明ありがとうございます
https://stackoverflow.com/a/47784683
このように構造体を表現しようとする試みはいろいろありましたが、結局のところ、これはPythonの限界であり欠点だと言える気がします。ADT(algebraic data type)には学校の授業でOCamlを通じて初めて触れましたが、仕事ではこのように真似をするしかないというのは少し残念でもあります。
ilotokiさんが作られたライブラリは、ADTに最も近い事例と見てよさそうです。いつか標準ライブラリに含まれ、広く使われるようになるとよいですね。
Messageの実装を Union で行うと、メソッド継承を利用できません。たとえば上のように
.processメソッドを追加すると、すべてのバリアントで.process()メソッドを使えます。また、私が説明した repr は「その enum のバリアントとしての repr」を意味しています。
たとえば fieldenum が repr をラップして呼び出すと、次のように実行されます。
カスタム
__repr__がないと、Messageenum の下位バリアントであることが表現されません。Quitはユニットバリアントなので、呼び出しなしで使います。また、呼び出しが必要なバリアント種別である fieldless バリアントの場合は、シングルトンとして
is演算子で確認できます。fieldenum を使うと、このように見落としやすいさまざまな実装ディテールを自動的に面倒見てくれます。
もしPyCon Koreaで発表していただけたらどうかと、ご提案してみます。とても面白く拝見したので、制作の過程であったお話や説明を直接お聞きしたいです!
PyConで発表できたら本当に光栄だと思います。自分がやりたいと言ったからといって実現できるかは分かりませんが(^^;)、考えてみます。
それと、英語のREADMEでもOptionの例が説明されているとよいですね。
Optionは理解しやすく、親しみやすくアプローチできるはずです。ドキュメント上の説明順でも、Optionを先に説明したほうがよりよい気もします。
英語のドキュメントはまだ準備中のため、少し内容が薄いです……。韓国語ドキュメントが十分に成熟したら、英語に翻訳しようと思っています。あるいは、関連するPRも歓迎します!
私もまず
Optionを先に紹介するほうがよさそうだと思います。修正します。おお、すごいですね!!
リンクしていただいた韓国語ドキュメントのサンプルコードに修正点があります。
お知らせいただきありがとうございます。修正しました!
GNとして投稿すべきでしたが、間違えて通常投稿にしてしまいました;;
修正しておきました。
ありがとうございます〜