【问题标题】:variable argument vs list in Python as function argumentsPython中的变量参数与列表作为函数参数
【发布时间】:2019-03-29 02:57:03
【问题描述】:

我想了解何时应该在 Python 2.7 的函数参数中使用可变参数和列表类型

假设我编写了一个处理 URL 列表的函数。我可以用两种不同的方式定义函数:

选项 1:

def process_urls(urls):
  if not isinstance(urls, list) or  isinstance(urls, tuple): 
      raise TypeError("urls should be a list or tuple type")

选项2:

 def process_urls(*urls):
      # urls is guaranteed to be a tuple

选项 2 保证 urls 是一个元组,但可以接受随机数量的位置参数,这些参数可能是垃圾,例如 process_urls(['url1', 'url2'], "this is not a url")

从编程的角度来看,哪个选项更受欢迎?

【问题讨论】:

  • 似乎有点基于意见。为什么假设这两种方法中的一种是绝对可取的?
  • 第一种解决方案的优点是您可以将迭代器传递给它,这是我看到的唯一区别。在这种特殊情况下,我想我会支持选项 1。
  • 如果可能的话,我宁愿使用process_url(url) 并使用标准函数(在本例中为map)来创建批处理。

标签: python


【解决方案1】:

两者都不是最好的。每种风格在不同情况下都有好处。

在大多数情况下,使用单个可迭代参数会更好,尤其是在调用者已经将 URL 打包到列表中的情况下。如果他们有一个列表并且需要使用 varargs 样式,他们需要调用process_urls(*existing_list_of_URLs),这会不必要地解包然后重新打包参数。正如John Kugelman 在他的回答中所建议的那样,您可能不应该使用显式类型检查来强制执行参数的类型,只需假设它是可迭代的并从那里开始工作。

如果您的函数主要使用单独的 URL 调用,则使用可变参数列表可能比需要列表更好。例如,可能 URL 是这样硬编码的:process_urls("http://example.com", "https://stackoverflow.com")。或者它们可能在单独的变量中,但要使用的特定变量直接编码在:process_url(primary_url, backup_url)

最后一个选项:支持这两种方法!您可以指定您的函数接受一个或多个参数。如果它只有一个,它需要一个包含 URL 的可迭代对象。如果它得到多个参数,它希望每个参数都是一个单独的 URL。这可能是这样的:

def process_urls(*args):
    if len(args) == 1:
        args = args[0]

    # do stuff with args, which is an iterable of URLs

这样做有一个缺点,它自己传递的单个 URL 字符串将被错误地识别为 URL 序列,每个 URL 都由原始字符串中的单个字符组成。这是一个非常尴尬的失败案例,因此您可能需要明确检查它。您可以选择引发异常,或者只接受单个字符串作为参数,就好像它在容器中一样。

【讨论】:

    【解决方案2】:

    第一个,但没有类型检查。类型检查杀死duck typing。如果调用者想要传入一个生成器、一个集合或其他可迭代对象怎么办?不要将它们限制为列表和元组。

    【讨论】:

    • 那为什么不检查序列和生成器呢?如果要以多种方式使用/“滥用”一个函数,那么对错误处理和类型检查以使函数尽可能“安全”是有意义的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 2014-12-28
    相关资源
    最近更新 更多