(标题和阅读Alex的答案后更新的内容)函数返回一个可迭代或不可迭代的函数取决于它的输入是Pythonic吗?
总的来说,我认为,它被认为是不好的形式(非Python化)的功能,有时会返回一个迭代,有时根据其参数的单个项目。
例如,struct.unpack
总是返回一个元组,即使它只包含一个项目。
我试图完成一个模块的API和我有,可以采取一个或多个参数(通过*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.
所以它返回一个单一的项目,如果有只有一个参数,否则返回一个列表。现在我认为这很好,一点也不令人困惑,但我怀疑其他人可能会不同意。
最常见的用例,这些功能将只想要一个单一的项目回来,所以总是返回一个列表(或元组)觉得不妥:
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
另一种选择是有两个功能:
a = s.read(10)
b, c = s.read_list(5, 5)
这是好的,但它使API变得混乱,并且要求用户记住两倍的功能而不增加任何值。
所以我的问题是:有时会返回一个迭代,有时会单个项目混淆和un-Pythonic?如果是这样,最好的选择是什么?
更新:我觉得一般的共识是,这是很调皮只返回一个可迭代的时候。我认为大多数情况下最好的选择是总是返回迭代,即使它只包含一个项目。
话虽如此,对于我的具体情况,我想我会去分裂成两个函数(read(item)
/readlist(*items)
),推理是,我认为,单个项目的情况下会更经常发生比多个项目案例,所以它使得它更易于使用,并且API更改对用户来说不会有问题。
谢谢大家。
+1。有时成为事物,有时候成为事物清单通常是一个错误。 Python为%格式化做了这个,这被广泛认为是一个错误和令人讨厌的陷阱。 – bobince 2009-09-22 17:32:46
我很害怕人们会这样说 - 当你清楚地只询问一件物品时,只是感觉很难得到一份清单! – 2009-09-22 18:27:48
@Scot Griffiths:恕我直言,潜在的错误是由于过于聪明而导致简单变量可能导致的问题。为什么不使用像'def read(a_tuple):'而不是使用'* args'的方法? – voyager 2009-09-22 19:40:45