これを行うには、次の 2 つの方法があります。
- 委任。すでに Python で使用されています。最も Pythonic です。組み込み型では機能しません。まさにあなたが探しているものではありません。
- シングルディスパッチ。まだ PEP です。組み込み型で機能します。まさにあなたが探しているもの。
委任
通常、操作対象のオブジェクトに責任を委任し、関数にロジックを実装しません。
次に例を示しますlen
。の実装len
は非常に簡単です。
def len(obj):
return obj.__len__()
異なるタイプ ( str
、list
、tuple
...) には異なる実装がありますが、それらはすべて同じ関数で動作します。
で動作する独自の型を定義したい場合は、次のようにしlen
ます。
class MyTypeOfLength3(object):
def __len__(self):
return 3
o = MyTypeOfLength3()
print len(o)
# 3
あなたの場合、次のようなものを実装しますlen
。
(注: これは の実際のコードではありませんが、len
ほぼ同等です。)
シングルディスパッチ
もちろん、場合によっては、それが実用的でないこともあります。それがあなたのケースなら、"Single Dispatch" PEP 443がおそらくあなたが探しているものです。
探しているものを実現する新しいデコレータを提案します:
>>> from functools import singledispatch
>>> @singledispatch
... def fun(arg, verbose=False):
... if verbose:
... print("Let me just say,", end=" ")
... print(arg)
...
>>> @fun.register(int)
... def _(arg, verbose=False):
... if verbose:
... print("Strength in numbers, eh?", end=" ")
... print(arg)
...
>>> @fun.register(list)
... def _(arg, verbose=False):
... if verbose:
... print("Enumerate this:")
... for i, elem in enumerate(arg):
... print(i, elem)
関数をそのように定義したら、 を呼び出すことができ、Python はデフォルトの実装へのフォールバックの正しい実装 (またはここ)fun(something)
を見つけます。int
list
def fun(...): ...
したがって、元の関数を装飾するだけで済み、ユーザーは独自の型を追加できます。
注: コメントで指摘されているように、singledispatch
既に Python で実装されています。pkgutil.simplegeneric