Address
304 North Cardinal St.
Dorchester Center, MA 02124

Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM

Pythonのfunctoolsモジュールのpartialについて

【Python入門】functoolsモジュールのpartial関数とは?その基本的な使い方の解説

Pythonの便利モジュールfunctoolsのpartial関数についての解説

今回はPythonの便利なfunctoolsというモジュールが提供している、partial関数の解説です。

functoolsモジュールとpartial関数とは?

functoolsとは

公式ドキュメントにおいてfunctoolsモジュールについては次のように説明されています。

functools モジュールは高階関数、つまり関数に影響を及ぼしたり他の関数を返したりする関数のためのものです。一般に、どんな呼び出し可能オブジェクトでもこのモジュールの目的には関数として扱えます。

partial関数とは

そしてそのfunctoolsモジュールには、partial関数というものがあります。これは、公式ドキュメントでは次のように説明されています。

新しい partial オブジェクト を返します。このオブジェクトは呼び出されると位置引数 args とキーワード引数 keywords 付きで呼び出された func のように振る舞います。呼び出しに際してさらなる引数が渡された場合、それらは args に付け加えられます。追加のキーワード引数が渡された場合には、それらで keywords を拡張または上書きします。

どちらもよくわからない文章ですね。

そこで次の項目を読んで見てください。まずはpartial関数を使いたくなる場面をイメージしてみましょう。

functools.paritialのメリットとは?

まず以下のようなコードを考えてみます。

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です。

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

では上のコードに続けて、次のように書きます。

# パターン1
new_fnc=partial(greet, "Mary", "Tom")
new_fnc(time="Evening")

実行結果は、

Hi! Mary Tom !! Good Evening

となります。

これについて考えるときには、次の3点をよく頭に入れてください。

  • partialの対象となる関数greet
  • 関数greetが持っている引数の情報(今回はnameとtimeの2つ)

この使用例その1の結果では、timeの情報だけ変更しています。変更したいのはその部分だけで、他の引数(今回はname)はそのままです。したがって、timeのところだけ変更した書き方にしたいわけです。

new_fnc=partial(greet, "Mary", "Tom")

このpartialを使った部分は、変更の必要のないnameという引数の情報は「凍結」(固定)した状態の新しい関数オブジェクトを作成しています。まさにそれがpartialの機能なんですね。

そうすると、あとは変えたい引数のところだけを書けばいいわけです。

new_fnc(time="Evening")

まさにこれがその希望どおりの書き方になっています。いちいち変更する必要のない引数の情報を何度も書き直す手間がなくなっています。

今回は引数の種類が2つだけでしたが、もしこれが10種類とかになれば・・・そうとんでもない手間になりますよね。

その手間を省き、またコードもどの引数を変更したのか見やすくしてくれる。これが上述のようなpartialのメリットです。

使用例その2

上の使用例その1ではキーワード引数であるtimeの情報を変更しました。次にnameの情報を変更してみましょう。

# パターン2
new_fnc=partial(greet, time="Morning")
new_fnc("Jane", "Jack")

変更したいのはnameで、変更不要なのはtimeです。したがってtimeをpatialによって「凍結」(固定)させています。

実行結果は、

Hi! Jane Jack !! Good Morning

いい感じですね。

使用例その3

#パターン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'}
  • nameには、Lieが追加された
  • timeには、辞書が設定された

という点に着目してください。

以上、簡単ながらfuntoolsモジュールが提供するpartial関数についての解説でした。こうしたことを踏まえて、公式ドキュメントを読んでもらえればその内容は理解しやすいと思います。

最速でプログラミングをマスターするならTechAcademy [テックアカデミー] 【PR】がオススメです。

マイペースで学ぶなら世界最大級の動画学習サイトUdemyがオススメです。セールで安く買える講座も多数!

愛を分かち合いましょう