web-dev-qa-db-ja.com

Pythonでオーバーロードされた関数?

Pythonで関数をオーバーロードすることは可能ですか? C#では、次のようなことをします

void myfunction (int first, string second)
{
//some code
}
void myfunction (int first, string second , float third)
{
//some different code
}

そして、関数を呼び出すと、引数の数に基づいて2つが区別されます。 Pythonで似たようなことをすることは可能ですか?

81
Trcx

EDITPython 3.4の新しい単一ディスパッチジェネリック関数については、 http://www.python .org/dev/peps/pep-0443 /

通常、Pythonで関数をオーバーロードする必要はありません。 Pythonは 動的に型付けされる であり、関数のオプションの引数をサポートします。

def myfunction(first, second, third = None):
    if third is None:
        #just use first and second
    else:
        #use all three

myfunction(1, 2) # third will be None, so enter the 'if' clause
myfunction(3, 4, 5) # third isn't None, it's 5, so enter the 'else' clause
96
agf

通常のpythonでは、望むことはできません。 2つの近似があります。

def myfunction(first, second, *args):
    # args is a Tuple of extra arguments

def myfunction(first, second, third=None):
    # third is optional

ただし、本当にこれを行いたい場合は、確実に動作させることができます(伝統主義者を怒らせるリスクがあります; o)。つまり、必要に応じて引数とデリゲートの数をチェックするwrapper(*args)関数を作成します。この種の「ハック」は通常、デコレータを介して行われます。この場合、次のようなことを実現できます。

from typing import overload

@overload
def myfunction(first):
    ....

@myfunction.overload
def myfunction(first, second):
    ....

@myfunction.overload
def myfunction(first, second, third):
    ....

overload(first_fn)function(またはコンストラクター)が__call__(*args)methodは上記で説明した委任を行い、overload(another_fn)methodは追加されます委任できる関数。

あなたはここで似たような例を見ることができます http://acooke.org/pytyp/pytyp.spec.dispatch.html しかしそれはタイプによってメソッドをオーバーロードしています。それは非常に似たアプローチです...

更新:python 3に(引数タイプを使用して)同様の何かが追加されています- http://www.python.org/dev/peps/pep-0443/

46
andrew cooke

はい、可能です。以下のコードをPython 3.2.1で作成しました。

def overload(*functions):
    return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)

使用法:

myfunction=overload(no_arg_func, one_arg_func, two_arg_func)

overload関数によって返されるラムダは、無名引数の数に応じて呼び出す関数を選択することに注意してください。

解決策は完璧ではありませんが、現時点ではこれ以上何も書くことができません。

7
GingerPlusPlus

直接は不可能です。ただし、指定された引数に対して明示的な型チェックを使用できますが、これは一般的に嫌われています。

Pythonは動的です。オブジェクトに何ができるかわからない場合は、単に:を試して、そのメソッドを呼び出します。ただし、エラーは除きます。

型ではなく引数の数だけに基づいてオーバーロードする必要がない場合は、キーワード引数を使用します。

1
Jürgen Strobel

メソッドをオーバーロードすることは、Pythonでは扱いにくいです。ただし、dict、list、またはプリミティブ変数を渡す方法があります。

私は私のユースケースのために何かを試しましたが、これはここでメソッドをオーバーロードする人々を理解するのに役立ちます。

Stackoverflowスレッドの1つの使用例を見てみましょう。

異なるクラスからメソッドを呼び出すクラスオーバーロードメソッド。

def add_bullet(Sprite=None, start=None, headto=None, spead=None, acceleration=None):

リモートクラスから引数を渡します。

add_bullet(Sprite = 'test', start=Yes,headto={'lat':10.6666,'long':10.6666},accelaration=10.6}

またはadd_bullet(Sprite = 'test', start=Yes,headto={'lat':10.6666,'long':10.6666},speed=['10','20,'30']}

そのため、リスト、ディクショナリ、またはメソッドのオーバーロードからのプリミティブ変数の処理が実現されています。

あなたのコードで試してみてください

0
shashankS