Categories: Python

【Python】引数が異なる関数を定義する方法【オーバーロード】

この記事では、Pythonで関数のオーバーロードを実装する方法を解説します。

Pythonでは、「C++」や「C#」と同じように定義することはできませんが、functoolsモジュールを使うことでPythonでもオーバーロードを実装することができます。

オーバーロードとは、引数が異なる同じ名前の関数を定義することです。

以下のコードでは、異なる型の引数を受け取る同じ名前の関数を定義し、呼び出していますが、後に定義した関数しか呼び出すことができません。

def func(text: str):
    print(f'text: {text}')


def func(num: int):
    print(f'num: {num}')


func('abc')
# num: abc

func(10)
# num: 10

このようなコードに functoolsモジュールを用いることで、渡された引数の型によって呼び出す関数を変更させることができます。

それでは、オーバーロードする方法を見ていきましょう!

オーバーロードの実装方法

Pythonでオーバーロードを実装するには、標準ライブラリであるfunctoolsモジュールのsingledispatchデコレーターを使います。

from functools import singledispatch

以下の手順で定義します。

  • STEP1
    基準となる関数の定義
    基準となる関数にsingledispatchデコレーターを付けます。関数名はここでは「func」にしておきます。
    @singledispatch
    def func(引数):
        # 何らかの処理
    オーバーロードするには、引数を1つ以上定義する必要がある
  • STEP2
    他の関数を登録
    次に、オーバーロード実装を追加します。

    この関数にもデコレーターを修飾させますが、singledispatchデコレーターを付けた関数から呼び出したregisterデコレーターを付けます。関数名はアンダースコア(_)にしましたが、基準となる関数(ここではfunc)と同じでなければなんでも良いです。

    @func.register
    def _(引数):
        # 何らかの処理

    singledispatchデコレーターは、1つ目の引数の型で呼び出す関数を決めています。なので、1つ目の引数の型がわかるように定義しなければなりません。

    型アノテーションを定義してある場合は、自動的に推測されます。

    @func.register
    def _(num: int):
        # 何らかの処理

    型アノテーションを定義してない場合は、registerデコレーターに型を指定する必要があります。

    @func.register(int)
    def _(num):
        # 何らかの処理
    

例として最初のコードをオーバーロードしてみましょう :

from functools import singledispatch

@singledispatch
def func(text: str):
    print(f'text: {text}')


@func.register
def _(num: int):
    print(f'num: {num}')


func('abc')
# text: abc

func(10)
# num: 10

このように、引数に渡した値の型によって呼び出す関数を変更することができました。

まとめ

この記事では、Pythonでオーバーロードを定義する方法を解説しました。

ポイント
  • functoolsモジュールのsingledispatchデコレーターを使う
  • オーバーロードする関数には引数が1つ以上必要
  • @関数名.registerで、他の関数を登録
  • 型アノテーションから型を推測してくれる
  • 1つ目の引数の型で分岐

同じような名前の関数を複数定義する際に使用すると、名前を考える労力を削れて良いかもしれません。是非とも機会があったら実装してみてください。

それでは今回の内容はここまでです!ではまたどこかで〜( ・∀・)ノ

ゆうまる

独学でプログラミングを勉強しているおじさん。いろんな言語を勉強したが浅く広くなためあまり仕事につながらない。また忘れっぽいため自分のブログを備忘録としても使っている。産まれてこのかたずっとネコを飼ってる生粋のネコ派。最近お腹が出てきて筋トレに奮闘中!

View Comments

Recent Posts

【Dart】コンストラクタのデフォルト引数について

Dartのコンストラクタのデフォルト引数…

4週間 ago

【Unity】有料アセットを無料で手に入れる方法

この記事では、Unityの有料アセットを…

5か月 ago

【Python】任意の秒数だけ処理を一時停止する方法【sleep()関数】

この記事では、Pythonで任意の秒数だ…

1年 ago

【Python】Wordの文書の新規作成と読み書き

この記事では、Pythonを使ってWor…

1年 ago

【Python】メタクラスって結局なんなの?

この記事では、Pythonのメタクラスに…

1年 ago