优雅地处理不同的参数类型
我有一个函数,在最简单的情况下,它可以在一系列迭代项上运行。
def foo(items):
for item in items:
# do stuff
有时候,我不想直接传递一个迭代项,而是提供一种获得迭代的方法的对象:
def foo(obj):
for item in obj.iteritems():
# do same stuff as above
我可以像这样合并这两种情况:
def foo(obj):
try:
items = obj.iteritems()
except ValueError:
items = obj
for item in items:
# do stuff
这工作得很好。 现在我看到第三个用例如下所示:
def foo(objs):
for item in itertools.chain.from_iterable(obj.iteritems() for obj in objs):
# do same stuff again
由于接口不兼容,我仍然可以使用try-except
方法。 但是,嵌套的try catch会变得非常难看。 当我想添加第四个用例时更是如此。 有没有办法解决这个问题,但不嵌套try
-blocks?
就目前而言,您应该至少使用两个方法,第三个方法是使用itertools.chain.from_iterable
结果调用第一个方法。 你也可能有* args的用法; 这取决于你的具体情况(提供一个真实的例子是有帮助的)。 你也可以使用一个简单的帮助函数来返回正确类型的迭代器。
也许这可能会解决:
def _foo_iter(obj):
try:
return obj.iteritems()
except AttributeError:
return obj
def foo(*objs):
for obj in objs:
for item in _foo_iter(obj):
必须同意克里斯:魔术的理解 - 所有的投入都会转而咬你。 如果你通过一个迭代器来迭代对象 - 迭代器的迭代器,那么你如何指定在什么级别上真正开始处理数据?
更好地坚持使用“列表或发生器”作为输入,然后预处理您的呼叫到该功能。
要检查一个对象是否可迭代:
import collections
isinstance(obj, collections.Iterable)
这应该让你摆脱一些问题。
另外,处理这些问题的一种方法是使用递归(不知道它是否适用):
def foo(obj):
if isinstance(obj, collections.Iterable):
for el in obj:
foo(el)
# now do stuff
链接地址: http://www.djcxy.com/p/3981.html