1

さまざまな引数タイプで呼び出されたときにさまざまなことを行う関数を作成しようとしています。具体的には、関数の1つに署名が必要です

def myFunc(string, string):

もう一方は署名が必要です

def myFunc(list):

引数が文字列であるかリストであるかを指定することが許可されていない場合、どうすればこれを行うことができますか?

4

6 に答える 6

2

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
于 2012-06-29T21:50:14.933 に答える
2

Pythonは、引数の数によってもオーバーロードをサポートしていません。あなたがする必要があります:

def foo(string_or_list, string = None):
    if isinstance(string_or_list, list):
        ...
    else:
        ...

これはかなりばかげているか、過負荷にならないように設計を再考するだけです。

于 2012-06-29T21:47:30.150 に答える
1

*argsおそらくより良い方法ですが、次のようなことができます。

def myFunc(arg1, arg2=None):
  if arg2 is not None: 
     #do this
  else:
     #do that

しかし、それはおそらくそれを行うためのひどい方法です。

于 2012-06-29T21:48:46.127 に答える
1

完璧な解決策ではありませんが、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
于 2012-06-29T22:53:30.233 に答える
0

できません。たとえば、クラスインスタンスメソッドを実行時に挿入できます。

__init__たとえば、クラスに複数ある場合は、または@classmethodなどの複数のを使用する方がよいでしょう。from_stringsfrom_sequence

于 2012-06-29T21:51:07.417 に答える
0

可変引数を取るものとして定義します。

def myFunc(*args):

len次に、とを介して引数の量とタイプを確認しisinstance、呼び出しを適切なケース固有の関数にルーティングできます。

ただし、オプションの名前付き引数を使用した場合は、コードがより明確になる可能性があります。オーバーロードをまったく使用しなかった方がよいでしょう。Pythonの方法ではありません。

于 2012-06-29T21:46:26.503 に答える