设计建议:基于Python中的参数类型控制流程?

时间:2014-07-22 06:18:28

标签: python typechecking

我正在编写以下形式的函数:

def fn(adict, b):
    """`adict` contains key(str): value(list). if `b` is a dict we have to
       call `do_something` for pairs of lists from `adict` and `b` for
       matching keys. if `b` is a list, we have to call `do_something`
       for all lists in `adict` with `b` as the common second
       argument.

    """
    if isinstance(b, dict):
        for key, value in adict.items():
            do_something(value, b[key])
    else:
        for key, value in adict.items():
            do_something(value, b)

def do_something(x, y):
    """x and y are lists"""
    pass

我知道这可能不是一个好的设计(Is it bad design to base control flow/conditionals around an object's class?)。但是编写两个函数,一个将b作为dict而另一个作为列表,似乎太多余了。有哪些更好的选择?

2 个答案:

答案 0 :(得分:1)

确实存在这种问题的模式,它被命名为"多次发送"或"多方法"。您可以在http://www.artima.com/weblogs/viewpost.jsp?thread=101605

找到一个(非常简单的)示例Python实现

使用此解决方案,您的代码可能如下所示:

from mm import multimethod

@multimethod(list, dict)
def itersources(sources, samples):
    for key, value in sources.iteritems():
        yield value, samples[key]

@multimethod(list, list)
def itersources(sources, samples):
    for key, value in sources.iteritems():
        yield value, samples

def fn(sources, samples):
    for value1, value2 in itersources(sources, samples):
        do_something_with(value1, value2)

答案 1 :(得分:0)

我使用“switch”方法:

class Demo(object):
    def f(self, a):
        name = 'f_%s' % type(a).__name__
        m = getattr(self, name)
        m(a)

     def f_dict(self, a):
        ...

代码根据参数的类型创建方法名称,然后在self中查找方法,然后调用它。