さまざまな引数タイプで呼び出されたときにさまざまなことを行う関数を作成しようとしています。具体的には、関数の1つに署名が必要です
def myFunc(string, string):
もう一方は署名が必要です
def myFunc(list):
引数が文字列であるかリストであるかを指定することが許可されていない場合、どうすればこれを行うことができますか?
さまざまな引数タイプで呼び出されたときにさまざまなことを行う関数を作成しようとしています。具体的には、関数の1つに署名が必要です
def myFunc(string, string):
もう一方は署名が必要です
def myFunc(list):
引数が文字列であるかリストであるかを指定することが許可されていない場合、どうすればこれを行うことができますか?
http://code.activestate.com/recipes/577065-type-checking-function-overloading-decorator/に、必要な処理を実行するレシピがあります。
基本的に、関数の各バージョンを@takes型と@returns型の宣言でラップします。関数を呼び出すと、型エラーをスローしないバージョンが見つかるまで、各バージョンが試行されます。
編集:これは縮小版です。それはおそらく良いことではありませんが、もしあなたがしなければならないなら、これがその方法です:
from collections import defaultdict
def overloaded_function(overloads):
"""
Accepts a sequence of ((arg_types,), fn) pairs
Creates a dispatcher function
"""
dispatch_table = defaultdict(list)
for arg_types,fn in overloads:
dispatch_table[len(arg_types)].append([list(arg_types),fn])
def dispatch(*args):
for arg_types,fn in dispatch_table[len(args)]:
if all(isinstance(arg, arg_type) for arg,arg_type in zip(args,arg_types)):
return fn(*args)
raise TypeError("could not find an overloaded function to match this argument list")
return dispatch
仕組みは次のとおりです。
def myfn_string_string(s1, s2):
print("Got the strings {} and {}".format(s1, s2))
def myfn_list(lst):
print("Got the list {}".format(lst))
myfn = overloaded_function([
((basestring, basestring), myfn_string_string),
((list,), myfn_list)
])
myfn("abcd", "efg") # prints "Got the strings abcd and efg"
myfn(["abc", "def"]) # prints "Got the list ['abc', 'def']"
myfn(123) # raises TypeError
Pythonは、引数の数によってもオーバーロードをサポートしていません。あなたがする必要があります:
def foo(string_or_list, string = None):
if isinstance(string_or_list, list):
...
else:
...
これはかなりばかげているか、過負荷にならないように設計を再考するだけです。
*args
おそらくより良い方法ですが、次のようなことができます。
def myFunc(arg1, arg2=None):
if arg2 is not None:
#do this
else:
#do that
しかし、それはおそらくそれを行うためのひどい方法です。
完璧な解決策ではありませんが、2番目の文字列引数が合法的にならない場合は、次のNone
ことを試してみてください。
def myFunc( firstArg, secondArg = None ):
if secondArg is None:
# only one arg provided, try treating firstArg as a list
else:
# two args provided, try treating them both as strings
できません。たとえば、クラスインスタンスメソッドを実行時に挿入できます。
__init__
たとえば、クラスに複数ある場合は、または@classmethod
などの複数のを使用する方がよいでしょう。from_strings
from_sequence
可変引数を取るものとして定義します。
def myFunc(*args):
len
次に、とを介して引数の量とタイプを確認しisinstance
、呼び出しを適切なケース固有の関数にルーティングできます。
ただし、オプションの名前付き引数を使用した場合は、コードがより明確になる可能性があります。オーバーロードをまったく使用しなかった方がよいでしょう。Pythonの方法ではありません。