2012-07-23 42 views
1

我剛剛花了一天的時間找到由於賦值語句末尾的逗號造成的錯誤。找到我的bug的困難被第三方回調庫加劇了,它捕獲異常,但它讓我想知道爲什麼Python(2.x)不會引發語法錯誤而不是創建元組。考慮以下內容Python竅門:簡單分配結束時的流浪逗號

>>> a = 1, 
>>> a 
(1,) 

正如您所看到的,尾隨逗號會創建一個單例元組。這並不違反Python語法(請參閱http://docs.python.org/reference/expressions.html#grammar-token-expression_list),但它肯定會導致一些意想不到的結果,例如

>>> a == 1, 
(False,) 

VS

>>> (1,) == a 
True 

雖然我現在明白這是怎麼回事,我很疑惑,爲什麼Python的允許這種語法,而不需要明確的括號來創建一個元組。 有沒有這種行爲是必要的,或者至少是有利的?過去7年來,我一直使用Python進行編程,我從來不需要用這種方式創建單例。在大多數方面,Python是一種非常可讀和明確的語言。這個特殊的「特徵」好像是非pythonic。

+0

不知道最後一句話......「顯式比隱式更好。」 – 2012-07-23 22:10:54

+1

我建議與語言維護人員取得聯繫,但這裏並不是這個問題可能引發的討論的好地方。簡短的答案是「這是如何實現的」,對於更長的解釋,你應該看看文檔或郵件列表,而不是SO。 – 2012-07-23 22:12:57

+0

@ IgnacioVazquez-Abrams,明確說要創建一個元組意味着在其周圍放置括號,對吧? – 2012-07-23 22:15:39

回答

7

這裏的吉多·範羅蘇姆,創造者Python中,explaining的語法此位是怎麼來的:

添加類似陣列的接口的元組

一個後果是,我 必須想出某種方式與 長度解決的元組的邊緣情況0或1.我從ABC取得的規則之一是,每個數據 打印或轉換爲字符串時都應該表示通過 表達式是語言解析器的有效輸入。所以,它 之後,我需要有0和1長度元組符號。 與此同時,我不想失去一元組與012xx單元之間的區別,所以我決定採用一種醜陋但實用的方法,其中一個尾隨逗號將 表達式轉換爲一元組和「()」將表示一個零元組。 Python的元組語法除了這裏通常不需要括號 - 通過「nothing」代表空的 元組可能太容易掩蓋真正的拼寫錯誤。

另請參閱此PythonInfo維基TupleSyntax,特別是「...它是定義元組的逗號,而不是括號」。

雖然這個語法不美麗(圭多說醜,但務實),我不認爲這是一個棘手的問題。真正的難題是你的第三方庫「陷阱例外」,因此隱藏了關於你的錯誤的重要信息。

+0

謝謝,史蒂文。我想圭多肯定有一些理由。對第三方庫沒有意見分歧,但仍然很麻煩的是,在大量代碼中難以發現的流氓逗號應該花費我一天的努力。 – 2012-07-23 23:46:33

2

有一個例子,它派上用場,交換兩個值。當然你可以在這裏使用明確的括號,但沒有它們看起來會更好。

a, b = b, a 
+0

我的問題只涉及單身人士的情況。對於元組中兩個或多個元素的有用性沒有分歧。我一直使用它。 – 2012-07-23 23:51:59

2

對不起,我沒有足夠的代表評論,所以這成爲它自己的答案。

這裏有兩個相關但不同的東西 - 元組解壓縮和只是創建一個元組文字。

元組拆包可在Mark Ransom的答案中找到。

元組雖然似乎是人們的絆腳石。它們不是用圓括號創建的,圓括號僅用於消歧。逗號定義了一個元組,所以a,是一個元素的元組,因爲,這就是元組,是一個逗號:)。 (需要說明的是,對於空的元組,而不是,看起來醜陋,我們得到堅持(),這也許就是人似乎有這個困難的根源。)

+0

+1。以下是PythonInfo Wiki的基本重述:[TupleSyntax](http://wiki.python.org/moin/TupleSyntax)。 – 2012-07-23 22:55:58