在使用静态绑定的语言(如java)中,您可以定义多个具有相同名称但参数不同的函数。学习Python,直到现在,我认为缺乏这个主要是"安全问题"(就像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
我发现这非常方便,因为不需要任何条件来选择要执行的正确操作。此外,此代码使重载更容易,因为可以决定只重载其中一个函数或两个函数。
试图在 Python 中处理这样的情况,我只找到不方便的解决方案,例如一些检查类型的 if 子句。
有没有更好的方法?
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?
看看这个问题:python中isinstance()和type()之间的差异
如果您最终执行了建议的 if 类型方法,您可能需要考虑鸭子类型或 isinstance 替代方案
您的问题可以通过使用通用方法/函数来解决。这些不是内置的python,但可以通过第3方库来连接,或者你自己编写一个。
几年前,我一直在愉快地使用PEAK规则,但是虽然它应该仍然有效,但它似乎已经失宠了。
新的 PEP 443(单参数调度)伴随着外部实现,单调度。 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)
您给出的特殊情况似乎是无论如何都不需要重载的情况。
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重载的问题,这是一个可能有助于理解为什么没有它不被视为问题的一个答案。