Pythonic是否可以根据函数的输入返回可迭代或不可迭代的函数?

Sco*_*ths 7 python return-value

(阅读Alex的答案后更新了标题和内容)

一般来说,我认为它被认为是一种函数的坏形式(非Pythonic),有时根据其参数返回可迭代的,有时是单个项.

例如,struct.unpack即使它只包含一个项目,也总是返回一个元组.

我正在尝试最终确定模块的API,并且我有一些函数可以采用一个或多个参数(via *args),如下所示:

a = s.read(10)        # reads 10 bits and returns a single item
b, c = s.read(5, 5)   # reads 5 bits twice and returns a list of two items.
Run Code Online (Sandbox Code Playgroud)

因此,如果只有一个参数,则返回单个项目,否则返回列表.现在我认为这很好,并不会令人困惑,但我怀疑其他人可能不同意.

这些函数最常见的用例是只返回一个项目,所以总是返回一个列表(或元组)感觉错误:

a, = s.read(10)       # Prone to bugs when people forget to unpack the object
a = s.read(10)[0]     # Ugly and it's not clear only one item is being returned
Run Code Online (Sandbox Code Playgroud)

另一个选择是有两个功能:

a = s.read(10)
b, c = s.read_list(5, 5)
Run Code Online (Sandbox Code Playgroud)

这没关系,但它使API混乱并要求用户记住两倍的功能而不添加任何值.

所以我的问题是:有时会返回一个可迭代的,有时一个项目令人困惑和非Pythonic?如果是这样,什么是最好的选择?


更新:我认为普遍的共识是,有时只返回一个迭代是非常顽皮的.我认为大多数情况下最好的选择是始终返回iterable,即使它只包含一个项目.

话虽如此,对于我的特殊情况,我认为我会去分成两个函数(read(item)/ readlist(*items)),理由是我认为单项情况会比多项情况发生得多,所以它更容易使用和API改变对用户来说问题较小.

感谢大家.

Est*_*ber 12

如果你有时会返回迭代器,而另一些则返回单个对象,我会说返回总是一个迭代器,所以你不必考虑它.

通常,你会在需要迭代器的上下文中使用该函数,所以如果你必须检查它是一个迭代列表或者一个对象只做一次工作,那么它更容易返回一个迭代器和总是迭代,即使它只有一次.

如果你需要做一些不同的事情,如果你返回一个元素,只需使用if len(var):.

记住,一致性是一种有价值的好处.

我倾向于返回一个一致的对象,而不是必然的相同类型,但如果我返回一个可迭代的,我总是返回一个可迭代的.

  • +1.有时候做一件事,有时候成为一个列表,通常是一个错误.Python为%-formatting做了这个,这被广泛认为是一个错误和令人讨厌的陷阱. (2认同)