我希望一个函数能够将字符串列表或多个字符串作为参数作为 *args

问题描述

我有一个函数,它应该能够将多个字符串参数作为 *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 中的最佳实践时,就是这样。