用Pythonic的方法生成一个可以接受一个iterable或任意数量的参数的函数?
这真的是制作一个可以接受一个iterable或任意数量的参数并对每一个参数进行处理的函数的最具python风格的方法吗用Pythonic的方法生成一个可以接受一个iterable或任意数量的参数的函数?,python,python-3.x,function,arguments,Python,Python 3.x,Function,Arguments,这真的是制作一个可以接受一个iterable或任意数量的参数并对每一个参数进行处理的函数的最具python风格的方法吗 from collections.abc import Iterable def for_each(*args): """Take any number of arguments or an iterable and do something with them. Shouldn't throw an error or print anything when
from collections.abc import Iterable
def for_each(*args):
"""Take any number of arguments or an iterable and do something with them.
Shouldn't throw an error or print anything when no arguments are given.
"""
if (len(args) == 1
and isinstance(args[0], Iterable)
and not isinstance(args[0], str)):
# Is this really the most Pythonic way to do this?
args = args[0]
for arg in args:
# heavily simplified
print("done", arg)
for_each(1, 2)
for_each(['foo', 'bar'])
for_each((3, 4, 5))
for_each() # does essentially nothing, like it should
for_each("string") # don't loop over the characters
for_each(6)
输出:
done 1
done 2
done foo
done bar
done 3
done 4
done 5
done string
done 6
我得到了这个有效的答案,但因为我实际上是在寻找一个更干净的方法,所以我提出了这个新问题
这是可行的,但在我看来,检查是相当丑陋的,我希望有更简单、更干净的方法来实现这一点输出应保持不变。python的方法是不要。选择一个,让调用方提供正确的参数:
没有什么好办法可以随心所欲地去做,因为你天生就是在猜测打电话的人的意图。你必须计算参数的数量,然后你必须担心像str这样看起来像iterables但不是的类型,或者它们应该是
如果必须按照您想要的方式进行,那么您的原始示例将尽可能好,但它仍然存在缺陷。假设用户希望将字符串视为可编辑字符串;您的方法仍然要求它们为每个函数编写([“foo”]),在这种情况下,为什么要无缘无故地使函数的实现复杂化呢。是的,我非常清楚,大多数情况下,最好是强制函数用户以特定的格式传递参数。问题不是一般的最佳实践,而是实现这样一个功能的最佳方式。没有好的方式,因为你天生就是在猜测调用者的意图。你必须计算参数的数量,然后你必须担心像
str
这样的类型看起来像iterables,但不是,或者它们应该是。那么你是说我的原始示例是完美的,没有什么可以改进的吗?我明白没有好的方法,但必须有一种比其他方法更好的方法。不,我是说你的原创作品是你能得到的最好的,但它仍然有缺陷。假设用户希望将字符串视为iterable;你的方法仍然要求他们为每一个([“foo”])编写,在这种情况下,为什么要无缘无故地使函数的实现复杂化呢?在理想的世界中,要么str
实例根本不适合,要么会有一个独特的char
类型,在str
上迭代就会产生。即使如此,这也不一定会阻止某人编写自己的类型,实现自己类型的迭代器。
# Iterable only: caller wraps the arguments
def for_each(iterable=None):
if iterable is None:
iterable = ()
# or just return now, if that's an option
for arg in iterable:
...
foreach((1,2,3))
# separate args: caller unpacks the arguments
def for_each(*args):
for arg in args:
...
x = [1,2,3]
for_each(*x)