Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
今回はPythonの便利なfunctoolsというモジュールが提供している、partial関数の解説です。
Contents
公式ドキュメントにおいてfunctoolsモジュールについては次のように説明されています。
functools
モジュールは高階関数、つまり関数に影響を及ぼしたり他の関数を返したりする関数のためのものです。一般に、どんな呼び出し可能オブジェクトでもこのモジュールの目的には関数として扱えます。
そしてそのfunctoolsモジュールには、partial関数というものがあります。これは、公式ドキュメントでは次のように説明されています。
新しい partial オブジェクト を返します。このオブジェクトは呼び出されると位置引数 args とキーワード引数 keywords 付きで呼び出された func のように振る舞います。呼び出しに際してさらなる引数が渡された場合、それらは args に付け加えられます。追加のキーワード引数が渡された場合には、それらで keywords を拡張または上書きします。
どちらもよくわからない文章ですね。
そこで次の項目を読んで見てください。まずはpartial関数を使いたくなる場面をイメージしてみましょう。
まず以下のようなコードを考えてみます。
from functools import partial
def greet(*name, **time):
print("Hi!" ,*name, "!! Good", time)
greet("Mary", "Tom", time="Morning")
実行すると、
Hi! Mary Tom !! Good Morning
となります。
さて、今回の関数greetは2「種類」の引数を持っています。
1種類目は、名前についての引数。もう1種類は時間についての引数(これはキーワード引数です)です。
そしてこの関数greetを使うときに、時間についてだけ変更(例:上のMorningからEveningへ)したいときがあるかもしれません。その場合は次のように、
greet("Mary", "Tom", time="Evening")
とすればいいわけですが、「”Mary”, “Tom”」の部分は同じことを繰り返して書くハメになっています。これって面倒じゃないですか?変えたいのは1箇所だけで、後はそのままでいいのに、いちいち変わらないところをまた書くというのは手間ですよね。
変えたいところだけ変えて書ければ便利ですよね?そんなときに使えるのが今回紹介するfunctools.partialです。
from functools import partial
def greet(*name, time): # nameは可変長引数
print("Hi!" ,*name, "!! Good", time)
greet("Mary", "Tom", time="Morning")
今回の解説では、このコードのあとに次のコードを付け足していくようにします。
仮引数nameについては、可変長引数(*がついている)であることに注意してください。
可変長引数については、過去記事「Pythonの引数*args, **kwargsとは?その解説」をごらんください。
では上のコードに続けて、次のように書きます。
# パターン1
new_fnc=partial(greet, "Mary", "Tom")
new_fnc(time="Evening")
実行結果は、
Hi! Mary Tom !! Good Evening
となります。
これについて考えるときには、次の3点をよく頭に入れてください。
この使用例その1の結果では、timeの情報だけ変更しています。変更したいのはその部分だけで、他の引数(今回はname)はそのままです。したがって、timeのところだけ変更した書き方にしたいわけです。
new_fnc=partial(greet, "Mary", "Tom")
このpartialを使った部分は、変更の必要のないnameという引数の情報は「凍結」(固定)した状態の新しい関数オブジェクトを作成しています。まさにそれがpartialの機能なんですね。
そうすると、あとは変えたい引数のところだけを書けばいいわけです。
new_fnc(time="Evening")
まさにこれがその希望どおりの書き方になっています。いちいち変更する必要のない引数の情報を何度も書き直す手間がなくなっています。
今回は引数の種類が2つだけでしたが、もしこれが10種類とかになれば・・・そうとんでもない手間になりますよね。
その手間を省き、またコードもどの引数を変更したのか見やすくしてくれる。これが上述のようなpartialのメリットです。
上の使用例その1ではキーワード引数であるtimeの情報を変更しました。次にnameの情報を変更してみましょう。
# パターン2
new_fnc=partial(greet, time="Morning")
new_fnc("Jane", "Jack")
変更したいのはnameで、変更不要なのはtimeです。したがってtimeをpatialによって「凍結」(固定)させています。
実行結果は、
Hi! Jane Jack !! Good Morning
いい感じですね。
#パターン3
new_fnc = partial(greet, "Mary", "Tom", time="Evening")
new_fnc("Lie", time={"Evening", "Afternoon", "Morning"})
この例では、引数nameの情報にもう新しい名前の”Lie”を付け加えました。そして引数timeは辞書形式にしています。
実行結果は、
Hi! Mary Tom Lie !! Good {'Afternoon', 'Morning', 'Evening'}
という点に着目してください。
以上、簡単ながらfuntoolsモジュールが提供するpartial関数についての解説でした。こうしたことを踏まえて、公式ドキュメントを読んでもらえればその内容は理解しやすいと思います。
最速でプログラミングをマスターするならTechAcademy [テックアカデミー] 【PR】がオススメです。
マイペースで学ぶなら世界最大級の動画学習サイトUdemyがオススメです。セールで安く買える講座も多数!