【问题标题】:I want a function to be able to take as an argument both a list of strings or several strings as *args我希望一个函数能够将字符串列表或多个字符串作为参数作为 *args
【发布时间】:2021-07-24 16:22:52
【问题描述】:

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

【问题讨论】:

  • 这些都不起作用@Jazzlike_?如果是这样,请检查那个。

标签: python function arguments args keyword-argument


【解决方案1】:

在 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

【讨论】:

    【解决方案2】:

    如果它是一个列表,这将获取 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是元组还是元组中的列表,甚至是多个列表的元组都没有关系。

    【讨论】:

    • 如果stuff[0] 是一个列表,那么他们可能还想遍历列表的其余部分(例如stuff[1]
    • 另外 isinstance() 也不是 更好 只是在处理子类化等情况下不同。
    • @Chris_Rands 听起来不像:“许多字符串参数作为 *args,或者字符串列表作为参数”
    • 也许-这取决于您是否阅读该描述或尝试匹配他们实现其功能的方式
    • 我宁愿看描述,这已经足够清楚了。实现首先有问题,否则他们不会问。
    【解决方案3】:

    在 Python 中编写函数时,通常最佳做法是假设函数的参数是已知且不变的。

    查看您的代码,如果您无论如何都将字符串数组传递给您的函数,似乎可以完成同样的事情。将数组传递给它后,只需打印其中的每个项目。如果只有一个项目,它将与仅打印该单个项目的功能相同。

    我建议这样写:

    def getStuff(stuff):
        for thing in stuff:
            print(thing)
    

    我确实意识到这并不是您想要的,但是当谈到 Python 中的最佳实践时,就是这样。

    【讨论】:

    • 添加到这个答案,有几个理由这样做。首先,它显然更干净,更易于阅读。其次,当您将参数传递给函数时,您通过调用对这些对象的引用来使用它们,通常使用变量。这意味着您不能迭代参数;无论如何,它们都必须在数组中。
    • 您可能想看看stackoverflow.com/questions/33542959/… 以获得不同的意见。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多