问题描述
我有一个函数,它应该能够将多个字符串参数作为 *args 或字符串列表作为参数。例如:
def getStuff(*stuff):
for thing in stuff:
print(thing)
getStuff("cat","mouse","dog")
getStuff(animals)
如果我以任何一种方式调用它,我都希望这个函数能够产生相同的结果。我目前正在使用以下非常简单的方法,但不是最干净的代码:
def getStuff(*stuff):
if type(stuff[0]) != list:
for thing in stuff:
print(thing)
else:
for thing in stuff:
for subthing in thing:
print(subthing)
有没有简单的方法来实现这一点?我正在寻找 Python 最佳实践。
解决方法
如果 args 元组是一个列表,这将采用它的第一个元素,否则我们可以遍历 args (stuff) 元组本身:
def getStuff(*stuff):
stuff = stuff[0] if isinstance(stuff[0],list) else stuff
for thing in stuff:
print(thing)
更优雅的解决方案,使用 itertools
:
import itertools
def getStuff(*stuff):
for thing in itertools.chain.from_iterable(stuff):
print(thing)
说明:itertools.chain.from_iterable
只是将嵌套的可迭代对象展平,以防 stuff
不仅仅是字符串元组。像这样,stuff
是元组还是元组中的列表,甚至是多个列表的元组都无关紧要。
在 Python 中,许多人更喜欢遵循 EAFP 原则而不是类型检查(又名 LBYL)——因为异常处理相当便宜——具体参见 What is the EAFP principle in Python? this answer。
以下是将其应用于示例代码的方法:
def getStuff(*stuff):
try:
stuff[0].split()
except AttributeError: # List objects have no split() method.
stuff = stuff[0]
for thing in stuff:
print(thing)
getStuff("cat","mouse","dog")
print()
animals = ['cow','horse','pig']
getStuff(animals)
输出:
cat
mouse
dog
cow
horse
pig
,
当您使用 Python 编写函数时,通常最佳做法是假设函数的参数是已知且不变的。
看看你的代码,如果你无论如何传递一个字符串数组,你的函数似乎可以完成同样的事情。将数组传递给它后,只需打印其中的每个项目。如果只有一个项目,它的工作方式与仅打印该单个项目的功能相同。
我建议这样写:
def getStuff(stuff):
for thing in stuff:
print(thing)
我确实意识到这并不完全是您要找的,但是当谈到 Python 中的最佳实践时,就是这样。