(標題和閱讀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