今の私の結論を言うと、好みです。
Union[X, None]
という3択目もありますが、好みだと思います。
はじめに
表題の件について、綴っていきます。
多少のただし書きを加えていますが、要は「好みです」としか書いていません。
お急ぎの方は好きな書き方を使ってください。
目次
PythonでUnion型の型ヒント
Python 3.10で動きがありました。
https://docs.python.org/ja/3/whatsnew/3.10.html#pep-604-new-type-union-operator
日本語のオススメはこちら
しかし、PEP 604: Allow writing union types as X | Y では、Union を使わなくとも、typescriptなどと同じように | 演算子を使って指定できるようになりました。
「int型またはstr型」を表すUnion[int, str]
は、int | str
と同じです。
https://docs.python.org/ja/3/library/typing.html#typing.Union
ユニオン型;
Union[X, Y]
はX | Y
と等価で X または Y を表します。
詳しいドキュメントはこちら:https://docs.python.org/ja/3/library/stdtypes.html#union-type
Optional型は、NoneとのUnion
https://docs.python.org/ja/3/library/typing.html#typing.Optional
Optional[X]
はX | None
(やUnion[X, None]
) と同等です。
Python 3.10の変更により、Union[X, None]
(X型またはNone)をX | None
と書けるようになったわけですね。
過去に記事も書いています
Optional型、どれで書く?
あなたの好みで書いてくださいね
PyCon JP 2021より
LTでアンケートがありました。
89 票の投票があり、Python 3.10 時代の nullable は X | None がちょっと優勢ということになりました 🎉
— 🍭 小笠原みつき (@YAMITZKY) 2021年10月16日
自分は Optional 派でしたが、派閥変えようと思います#pyconjp https://t.co/d1oNwiFwPZ
nikkieの見解
X | None
派です。
この派閥に属すまでの経緯を書きます。
Python 3.9で組み込み型(list
など)が型ヒントに使えるようになりました。
私は最初「え、なんで?」と飲み込めなかったんですよ、typing.List
で型ヒントしてきたのに、それがdeprecateされてlist
が望ましいといきなり言うだなんてあんまりだ!
PEPにあたっていくうちに、これは歓迎すべきという主張が理解できてきたんですね2。
そもそもPythonの型ヒントはオプショナルとして、言語は変更せずtypingモジュールを外付けする形で始まっています。
それが、組み込み型を型ヒントに使うよう変更できるまでに、型ヒントが普及したんですよ!
この流れの先にUnion
を|
で表せる変更もあるととらえています。
これも言語自体が型ヒントをサポート・拡張する深化であり、私は積極的に書いていきたい立場です。
Unionって打つより文字数が少ないですしね。
??「one obvious wayを志向するPythonなのに、Optional型の型ヒントは複数あるんですか?」
Zen of Pythonをご存知なのですね。
There should be one-- and preferably only one --obvious way to do it.
あいたたた。
そうなんですよ、Pythonなのにやり方が1つじゃないんですよ
メーリングリストの議論を追う
※膨大な分量があり、全部精読はできていません
Guido氏
はっとする投稿がありました。
ここから「やり方は1つじゃないんですね」という指摘は当たらないかもなあと感じています。
とらえ方が変わった投稿です。
「Optional
って要るんですか?Union[T, None]
だけでいいのではないでしょうか?」に、Guido氏が反対を示しています。
Guido氏の主張に表れているのは、人間にとっての読みやすさ4(理解しやすさ)だと思います
Every time I see Union[T, None] I have to read it carefully to see what it means.
When I see Optional[T] my brain moves on immediately
Union[T, None]
は都度注意深く読まなければならないOptional[T]
はただちに理解できる
意味内容が同じであっても、理解しやすさには違いがある。
Optional型の型ヒントは何通りも書けますが、全く同じやり方が重複しているわけではないと気づきました。
その点で、「Union[T, None]
とOptional[T]
」と複数通りありますが、これはやり方が1つでないとは言えないという立場です。
ちなみに??さんは私の心の中に住んでいます。
上でどちらを選ぶかは好みと書きましたが、開発チームの状況も1つの変数だと思います。
ある状況ではOptional[T]
に揃えた方がいいかもしれず、別の状況ではT | None
の方がいいかもしれません(そんなの決めない!がうまくいくケースもあるかも)。
なので、あなただけの好みだけでなく、一緒に開発する人の好みにも注意を払って決めてはいかがでしょうか。
余談:Inadaさんの指摘
日本人コミッターの稲田さんは否定的な立場でした。
その中で気になったのがこちら
"there is new way to do it but it may be much slower and use much memory, so you shouldn't use it unless you can ignore performance."
話の流れとしては
int | str
のように書けたら、見た目がよいのでみんな使うだろう- ただしパフォーマンスは劣る書き方を推奨される形になる
この状況への懸念を稲田さんは表明しているという理解です。
|
のパフォーマンスについて宿題事項に積まれました(ガンガン使っていきたいけど、懸念があるの?)
終わりに
PythonでOptional型の型ヒントについて書きました。
Pythonという言語が進化してきているため、Optional[X]
・X | None
・Union[X, None]
と3択があります。
私は好みで使えばよいという立場です。
私自身はX | None
派です。型ヒントの普及に思いを馳せながら日々書いています。
今回Guido氏の投稿で気づかされたように、Optional[X]
は明確に分かりやすい書き方であり、開発チームの状況によってどれを推奨するかは変わると思います(揃えないという選択肢も含めて)。
- 今日もナイスセクシー! Act-4の dear... よかった...↩
- それを話したスライドがこちらです:https://docs.google.com/presentation/d/1KJlSSS-ZDByqqg_HO0_EFGbXCBqR8OMzzWwz8xvGQkU/edit#slide=id.gac886c4914_0_51↩
- https://peps.python.org/pep-0604/#objections-and-responses↩
- Pythonに通底している思想だと思います↩