【Pyhton】ジェネリック関数【備忘録】

こんにちは、Retroidです。

過去記事にも書いてあるように、Fluent Pythonを読んでいるのですが、解説が細かくて、「なるほど、こういう意味なのか!」と感心させられることが多々ありました。

というわけで、Fluent Pythonで学んでためになったことを、これから度々書いていこうと思います。

著作権について

これから備忘録には、サンプルコードを示していきます。

Fluent Pythoのコードは、GitHubにてMITライセンスで公開されています。

おかげさまで安心して引用できます(^^)

※MITライセンスのコードは、コピーライトをしっかり貼れば、ほとんど制限なく利用できます。

免責

自分の勉強も兼ねているので、正確な知識を頭に入れて文章を書くように努めておりますが、間違っていた場合は教えてください。

不利益が出ても責任負えません(^_^;)💧

頑張って正確な記事を書けるように努めますm(_ _)m

ジェネリック関数について

ジェネリック」というと、芸能界の重鎮、黒柳徹子様が宣伝している「ジェネリック医薬品」が思い浮かびます。

このような場合のジェネリックとは、「後発の会社が開発した、特許切れの商品と同じような効果を持つ商品のこと」と認識しております。

一方で、プログラミングにおける、ジェネリック関数は、「第一引数の型に応じて、同じような処理を異なった方法で行う関数の集まり」です。

例えば、Pythonの型には、

  • 数値
  • シーケンス
  • マッピング
  • クラス
  • インスタンス
  • 例外

といったものがあります。

以下の例では、

  • str型(シーケンス型の一種)
  • numbers.Integral(intの仮想スーパークラス)
  • tuple型
  • abc.MutableSequence(ミュータブルなシーケンス型)
  • obj(Pythonでは全てがオブジェクトなので、多分↑4つが当てはまらなかったときは全部これで処理される?)

が第一引数として投げ込まれた際に、1つの関数(htmlize)へ投げ込んだにもかかわらず、投げ込まれた引数の型に応じて、それぞれの型に対応する関数へ振り分けられます。

なんで、int型じゃなくてnumbers.Integralなんだ?

とか

なんで、list型じゃなくてabc.MutableSequence型なんだ?

という疑問が出てくると思いますが、これは、intやlistのみならず、intやlistのベースとなったクラスより生成されたオブジェクトについても、処理の振り分けができるようにするためです。

つまり、このジェネリック関数は、int型やlist型はもちろん、互換性のある型についても、ちゃんと分けて処理できるってことです。

抽象基底クラスというものを理解すると良いらしいですが、retroidも現在勉強中の分野のため、このくらいにしておきます(^_^;)

さて、サンプルコードです。

import htmlは、もともとPythonに用意されているモジュールです。

文字列の &、<、および > を HTML セーフなシーケンスに変換するとのこと。

①⇒singledispatchでhtmlize関数をジェネリック関数にしている。

②⇒str型の引数が入った時に実行される関数

③⇒numbers.Integralが引数として入った時に実行される関数

④⇒tuple型または、abc.MutableSequenceが入ったときに実行される関数

って感じになります。

①のhtmlize関数の前に@singledispatchを入れることによって、htmlize関数をジェネリック関数にしています。

①自体は、object型を処理する関数です。

若干推測入るのですが、もし②−④までの条件が当てはまらなかったら①で処理されるのかな?と思いました。

不明瞭ですみません。

わかったら追記します。

 

というわけで、Pythonにおけるジェネリック関数の簡単な説明と、Pythonでジェネリック関数を使うには、@singledispatchを使えば良いよ!って話をしました。

自分も関数書いてて、「引数に入ってくる文字型ごとに処理を変えたいなぁ」と思うことが結構ありました。

これからは、@singledispatchをうまく使ってスマートなコードを書いていきたいと思います。

 

サンプルコードのライセンス

The MIT License (MIT)

Copyright (c) 2014 Luciano Ramalho

https://github.com/fluentpython/example-code/blob/master/LICENSE

参考文献

Fluent Python

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です