如何根据参数类型执行不同的操作

时间:2014-11-23 13:24:21

标签: python dynamic-binding static-binding

在使用像java这样的静态绑定的语言中,您可以定义多个具有相同名称但不同参数的函数。学习Python,到现在为止我认为缺少这个主要是因为"安全问题" (因为引号可能会将bool_parameter="False"解释为True)。我想我只需要更加小心。

现在我发现了一种情况,缺少静态绑定只是不方便。请考虑这个tupel:

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子句。

有更好的方法吗?

4 个答案:

答案 0 :(得分: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?

答案 1 :(得分:1)

查看此问题:Differences between isinstance() and type() in python

如果您最终建议采用if类型方法,您可能需要考虑鸭子类型或实例替代方案

答案 2 :(得分: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)

答案 3 :(得分: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重载的问题,而this is one answer可能有助于理解为什么它不被认为是没有它的问题。