我正在编写以下形式的函数:
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而另一个作为列表,似乎太多余了。有哪些更好的选择?
答案 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
中查找方法,然后调用它。