有两种方法可以做到这一点:
- 代表团。已经在 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)
一旦你这样定义了你的函数,你可以调用fun(something)
,Python 会找到正确的实现(int
或list
这里),回退到默认实现def fun(...): ...
。
因此,您只需要装饰您的原始函数,就完成了,您的用户可以添加他们自己的类型。
注意:正如评论中指出的,singledispatch
已经在 Python 中实现,它是pkgutil.simplegeneric