1

Java のような静的バインディングを使用する言語では、すべて同じ名前でパラメーターが異なる複数の関数を定義できます。Python を学んでいて、今までこれがないことを主に「安全上の問題」と考えていました (likeは引用符のためにbool_parameter="False"解釈される可能性がTrueあります)。もっと気をつけないといけないなと思いました。

ここで、静的バインディングの欠如が単に不便である状況を見つけました。このタペルを検討してください:

var = ((1, "foo"), (2, "bar"), (3, "potato"))

静的バインディングを使用してアイテムを削除するには、次のvarようにすることができます (疑似コード:

def del_item(int i):
    # search item with (x == i, *)
    # remove this item

def del_item(String s):
    # search item with (*, x == s)
    # remove this item

実行する適切なアクションを選択するために条件が必要ないため、これは非常に便利だと思います。さらに、このコードにより、関数の 1 つまたは両方をオーバーロードすることを決定できるため、オーバーロードが容易になります。

Python でこのような状況に対処しようとすると、型をチェックする if 句のような不便な解決策しか見つかりません。

より良い方法はありますか?

4

4 に答える 4

2

Python にはメソッドのオーバーロードがないため、引数の型を確認する必要があります。

def del_item(item):
    if type(item) is int:
        # search item with (x == item, *)
        # remove this item
    elif type(item) is str:
        # search item with (*, x == s)
        # remove this item
    else:
        # Maybe raise an exception?
于 2014-11-23T13:29:34.563 に答える
1

あなたの問題は、一般的なメソッド/関数を使用して取り組むことができます。これらは Python には組み込まれていませんが、サードパーティのライブラリを使用するか、自分で作成することができます。

私は数年前に PEAK ルールを使って楽しく仕事をしてきましたが、それでも機能するはずですが、少し人気がなくなったようです。

新しい PEP 443 (単一引数ディスパッチ) には、外部実装 singledispatch が伴います。https://pypi.python.org/pypi/singledispatch/3.4.0.3

これで、問題は次のように解決できます。

 from functools import partial
 from singledispatch import singledispatch


 var = ((1, "foo"), (2, "bar"), (3, "potato"))


 @singledispatch
 def del_predicate(value):
     pass


 @del_predicate.register(int)
 def _(v, candidate):
     return v == candidate[0]

 @del_predicate.register(str)
 def _(v, candidate):
     return v == candidate[1]


 def neg(f):
     def _f(*args):
         return not f(*args)
     return _f

 print filter(neg(partial(del_predicate, "foo")), var)
 print filter(neg(partial(del_predicate, 2)), var)
于 2014-11-23T13:53:33.803 に答える
1

この質問をチェックしてください: Python での isinstance() と type() の違い

提案された if 型のアプローチを実行することになった場合は、ダックタイピングまたは isinstance の代替を検討することをお勧めします。

于 2014-11-23T13:35:05.187 に答える
0

あなたが与える特定のケースは、とにかくオーバーロードが必要ないケースのようです。

def del_item(id):
    return tuple(item for item in var if not id in item)

別のオプションは、オプションのキーワード引数を使用することです

def del_item(string_id=None, number_id=None):
    if string_id is not None:
        return tuple(item for item in var if not item[1] == string_id)
    return tuple(item for item in var if not item[0] == number_id)

Python のオーバーロードに関する以前の質問はたくさんあります

于 2014-11-23T14:48:22.517 に答える