memoちょっとだけ背景説明なんでそんなことがしたくなったかというと、やっぱり定義を記述したらおしまいでいられる世界が理想なので。...)に属さないような中立的な表現が欲しくなったので。この記事は一言で言うならpythonのクラスの各フィールドにどうやってメタデータを持たせようか?ということに対するメモです。してpython?現状よく触るのがgoとpythonなのですが、goは直和型が素直に記述できないので1。dictやprotocolなどそこそこpythonでも悪くはない形で型チェックが可能になってきたかなーということが1つ。hintsは特殊で、実はこの部分が意外と便利に機能するのではないかという思いがあったりします。複雑な型パズルがしたいというよりは至る所にメタデータをガチャガチャとくっつけたいという気持ちになったためです(reflect-metadata周りでtypescriptでも機能する気がしますし、最悪ASTを取り出してあれこれするという形でも良いので、やっぱり結局手に馴染んだものでのプロトタイプという意味合いが強い気がします)。以下の様なpythonのコードがあったとします。Docのschemaの形式を利用することにします。何もメタデータ無しの現状では以下の様に素直に変換できますね。ageメタデータありの場合ここからが本題です。クラスに対するメタデータクラスに対するメタデータの方法は以下の2つが考えられそうです。...あるいはdescriptionなどはそのままdocstringが使えそうですね。...クラスの方は対応方法が色々ありそうなのでどうにかなりそうな気がします。クラスの各フィールドに対するメタデータ今度はクラスの各フィールドに対する話です。メソッドとデコレータ(上手くいかない)クラスのときと同様にフィールドに対するデコレータもと考えると、メソッドにデコレーターでメタデータを付加すれば良いということになりますが。...これはnameがメソッドであるというインターフェイスを前提としての記述になってしまうので嬉しくないです。以下の2つは違うので。Person().namePerson().name()そして可能ならDSLのためのベースとなるような記述が、他の部分の実際の実装に全く影響や前提を設けないというような形に持っていきたいです。プロパティとデコレータ(上手くいかない)それではということでプロパティにしてしまいましょう。duck-typingというやつです。...ついでにドキュメントのためのプロパティということを表すためにmarker的な機能を付与したデコレータに変えていきたいところですが。これはまだまだpropertyをwrapしたgenericなデコレーターの型付けがサポートされていないっぽいので無理です。...加えてpropertyを直接使うとインターフェイスを固定してしまいますね。attributeprint(p.name)素直にインスタンス変数として使える形になっていて欲しいものです。自前で定義したディスクリプターとデフォルト値(暫定的な回答)そんなわけで以下をどうにかこうにか満たしたいわけです。mypyの型チェックが通るようにしたい(なるべくmypyのpluginsなどには手を出したくない)利用方法に制限や前提を設けたくない(インターフェイスを固定したくない)色々考えてみた結果の暫定的な回答は自前でディスクリプターを定義してそれをデフォルト値として使うということでした。自前でディスクリプターを定義すると良いのかと言うと、pyramidのreifyの妙と同じ話で、プロパティの機能の裏側にあるディスクリプターとインスタンス変数の優先順位の関係で、インスタンス変数への上書きを制限しなくなります。str1dataclassesと似たような記述にすると言うと分かる人もいるかもしれません。dataclassesほど複雑ではないのでmypyの対応もpluginsという形での特別扱いは不要でした。20なぜディスクリプターが良いかなぜディスクリプターが良いかというとメタデータにアクセスする方法を提供してくれるからです。ディスクリプター自体は通常の属性アクセスでは__get__()が呼ばれるのですが。呼ばれる直接__dict__の中を覗くことでディスクリプタの実態にさわれます。<fieldのインスタンス>そんなわけでディスクリプタ自身にメタデータをもたせておけば、外見上は属性アクセスを担保しつつフィールド毎にメタデータを保持することも可能になります。"xxx"}実行時の感じとしては良さそうですね。実際に動く実装を作って以下のように使えるようになることを目指します。metadata=dict(doc="hmm"))デフォルト値とメタデータを保持するディスクリプターの定義自体は以下の様な感じになります。self.default実際に上手くmypyの型チェックをすり抜けるために少しhack的なものが必要です。HACKmypyにはあたかも以下が同じモノであるかのように見えるためのhackです。"xxx"})この様にやってあげると以下が実行もでき型チェックも通ります。None]'reifyのようにデコレーターベースになっていると、メソッドのような形で記述してdocstringでのdescriptionをという夢も膨らみますが前述の通りでまだ無理です。gist自分で動作確認したい人のためのgist。説明する気は無いですが、この知見を使ってのパッケージを作成中です。unionではないものの、メンバーをクラスに絞ってsubtypingを考えなければ。nominalなので。クラス自身をタグにという扱いでとりあえず今回の要件は満たせる(クラスは値構築子)。self.<name>に対するものなので大丈夫と言うような形。02:47pythonでmypyを騙してfieldにmetadataを付加したクラスを定義してみるTweet広告を非表示にする関連記事2019-10-12pythonのtyping_extensions.Protocolがなぜ嬉しいか(propertyの...mypyで使えるProtocolが便利という話の例。いうライブラリを作りました。componentという機能を追加した月別アーカイブはてなブログをはじめよう!podhmoさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。