Re:ミノ駆動本_読書py[6]参加記事

Re:ミノ駆動読書py[6]参加記事

先日、id:nikkie-ftnextさんと共同主催しているミノ駆動本_読書py[6]を開催しました。 pythonista-books.connpass.com

今回は第4章不変の活用を読みました。ミノ駆動本はJavaで書かれていますが、Javaでいう不変を定義できるfinalはPythonには存在しておらず落とし込むのが難しい場所です。 しかし、勉強会で色々話を伺って色々活用できそうなポイントがいくつかありました。まだ全て理解しきれている訳ではありませんが、いくつかご紹介します。

dataclassのfrozen=Trueの実装箇所(何をどうやっているのか)

私の中で最初に浮かんだ疑問です。 FrozenInstanceErrorというエラーを出力している箇所は見つけたので「ここじゃん」というのは分かりつつ、実装内容がイマイチわかってはいませんでした。

そのことを書いたところ、id:nikkie-ftnextさんが教えてくださりました(ありがたや、ありがたや・・・!)。同じように疑問を抱かれて、読まれたことがあったとのこと。

ソースは以下です。

github.com

詳しくは以下のScrapboxに書いてくださっていますが、

object.__setattr__

という属性の代入が試みた時に呼び出される(通常の代入時の動作と理解)ダンダーメソッドを用いているようです。

docs.python.org

scrapbox.io

scrapbox.io

scrapbox.io

field(default_factory=list)だと毎回デフォルト引数のインスタンスを生成してくれる

Pythonの引数って変な動きをしますよね?私も以前記事を書いたことがあるのですが、意図しない動きをするよね、という話題から挙げていただきました。

qiita.com

デフォルトファクトリ関数 field() に default_factory を指定した場合、そのフィールドのデフォルト値が必要とされたときに、引数無しで呼び出されます。 これは例えば、リストの新しいインスタンスを作成するために使います:

mylist: list = field(default_factory=list)

あるフィールドが (init=False を使って) init() から除外され、かつ、 default_factory が指定されていた場合、デフォルトファクトリ関数は生成された init() 関数から常に呼び出されます。 フィールドに初期値を与える方法が他に無いので、このような動きになります。

docs.python.org より引用。

これを使うことによってメソッドを呼び出した際に毎回意図せずに同じものを流用してしまう(結果、毎回インスタンスが作成されるのではなく、追加されてしまう)ことを防げる、ということでした。

カリー化

カリー化について昔、無職やめ太郎さんの次の記事を読んだ記憶はあったんですが何のことか覚えておらず、改めての勉強になりました。

qiita.com

私が理解できた範囲でいうと、1回で引数をまとめてドーン!と渡すのではなく分割して渡すことができる = 意味合いを分割できる、という点が良いなと思いました。 あとは引数を1回しか設定できなくなるので、setterが不要になる(setterってどこでも呼べちゃうので値が変わっちゃう恐れがありますよね)。ということは、これもまさにPythonで不変を実現できるポイントの1つなのかと理解しました。いわゆるDI(依存性の注入)チックなことが出来るとのことで学んで活用していきたいです。

良い型ヒントの書き方

こちらについては以下のリンクに詳しく書いていただいています(紹介していただきました)。

gihyo.jp

多重構造のlist, dictが入れ子になった時、型ヒントが分かりにくい状態になりますがその対策方法を教えてもらいました。 型ヒントを全く利用できていないのが正直なところですが、この記事を参考にしていきたいなと思いました。

おわりに

いや〜、勢いでブログ記事を書いたけど、全然理解できていないことばかりです!でも焦らず一歩ずつ学んで自分の血肉にしていこうと思います!!