作者 | 快快
來源 | 快學Python
當您運行 Python 代碼時,解釋器將首先解析它以將其轉換為 Python 字節碼,然後執行。解釋器將在程序執行的第一階段(也稱為解析階段)中發現 Python 中的任何無效語法。如果解釋器無法成功解析您的 Python 代碼,則意味著您在代碼中的某處使用了無效語法。解釋器將嘗試向您顯示該錯誤發生的位置。
當您第一次學習 Python 時,遇到 SyntaxError 可能會令人沮喪。Python 將嘗試幫助您確定代碼中無效語法的位置,但它提供的回溯可能有點令人困惑。有時,它指向的代碼非常好。
注意:如果您的代碼在語法上是正確的,那麼您可能會引發其他不是 SyntaxError 的異常。
今天,咱們就來看看Python中6個常見的語法問題。
當您第一次遇到 SyntaxError 時,了解為什麼會出現問題,以及如何修復 Python 代碼中的無效語法,會很有幫助。
在下面的部分中,您將看到可能引發 SyntaxError 的一些更常見的原因,以及如何修復它們。
在 Python 中有幾種情況,您無法對對象進行賦值。一些示例分配給文字和函數調用。在下面的代碼塊中,您可以看到一些嘗試執行此操作的示例,以及由此產生的SyntaxError 回溯:
>>> len('hello') = 5
File "<stdin>", line 1
SyntaxError: can't assign to function call
>>> 'foo' = 1
File "<stdin>", line 1
SyntaxError: can't assign to literal
>>> 1 = 'foo'
File "<stdin>", line 1
SyntaxError: can't assign to literal
第一個示例嘗試將值 5 分配給 len() 調用。SyntaxError 消息在這種情況下非常有用。它告訴你不能給函數調用賦值。
第二個和第三個示例嘗試為文字分配一個字符串和一個整數。相同的規則適用於其他文字值。回溯消息再次表明當您嘗試為文字賦值時出現問題。
您的意圖很可能不是為文字或函數調用分配值。例如,如果您不小心遺漏了額外的等號 (=),就會發生這種情況,這會將賦值轉換為比較。如下所示,比較是有效的:
>>> len('hello') == 5
True
Python 關鍵字是一組受保護的詞,在 Python 中具有特殊含義。這些詞不能用作代碼中的標識符、變量或函數名稱。它們是語言的一部分,只能在 Python 允許的上下文中使用。
錯誤使用關鍵字的常見方式有以下三種:
① 關鍵字拼寫錯誤;
② 缺少關鍵字;
③ 濫用關鍵字;
如果您在 Python 代碼中拼錯了關鍵字,則會收到 SyntaxError。例如,如果關鍵字 for 拼寫錯誤,會發生以下情況:
>>> fro i in range(10):
File "<stdin>", line 1
fro i in range(10):
^
SyntaxError: invalid syntax
該消息顯示 SyntaxError: invalid syntax ,但這不是很有幫助。回溯指向 Python 可以檢測到錯誤的第一個位置。要修復此類錯誤,請確保所有 Python 關鍵字拼寫正確。
關鍵字的另一個常見問題是當您完全忘記寫時:
>>> for i range(10):
File "<stdin>", line 1
for i range(10):
^
SyntaxError: invalid syntax
再一次,異常消息並沒有那麼有用,但回溯確實會嘗試為您指明正確的方向。如果從插入符號中移回,則可以看到 for 循環語法中缺少 in 關鍵字。
您還可以濫用受保護的 Python 關鍵字。請記住,關鍵字只允許在特定情況下使用。如果您錯誤地使用它們,那麼您的 Python 代碼中將包含無效的語法。一個常見的例子是在循環外使用 continue 或 break。這很容易在開發過程中發生,當您正在實現事物並碰巧將邏輯移到循環之外時:
>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
... print('jim found')
... break
...
File "<stdin>", line 3
SyntaxError: 'break' outside loop
>>> if 'jim' in names:
... print('jim found')
... continue
...
File "<stdin>", line 3
SyntaxError: 'continue' not properly in loop
在這裡,Python 可以很好地告訴您究竟出了什麼問題。消息“'break' 外循環”和“'continue' 未正確循環”可幫助您確定要做什麼。如果這段代碼在一個文件中,那麼 Python 也會有指向誤用關鍵字的插入符號。
另一個示例是,如果您嘗試將 Python 關鍵字分配給變量或使用關鍵字來定義函數:
>>> pass = True
File "<stdin>", line 1
pass = True
^
SyntaxError: invalid syntax
>>> def pass():
File "<stdin>", line 1
def pass():
^
SyntaxError: invalid syntax
通常,Python 代碼中無效語法的原因是缺少或不匹配的右括號、方括號或引號。這些在很長的嵌套括號行或更長的多行塊中很難發現。借助 Python 的回溯,您可以發現不匹配或丟失的引號:
>> message = 'don't'
File "<stdin>", line 1
message = 'don't'
^
SyntaxError: invalid syntax
在這裡,回溯指向無效代碼,其中在結束單引號之後有一個 t'。要解決此問題,您可以進行以下兩項更改之一:
① 用反斜槓轉義單引號 ('don't');
② 用雙引號將整個字符串括起來("don't");
另一個常見的錯誤是忘記關閉字符串。對於雙引號和單引號字符串,情況和回溯是相同的:
>>> message = "This is an unclosed string
File "<stdin>", line 1
message = "This is an unclosed string
^
SyntaxError: EOL while scanning string literal
您之前看到,如果您將逗號放在字典元素之外,您可能會得到 SyntaxError。Python 字典的另一種無效語法形式是使用等號 (=) 來分隔鍵和值,而不是使用冒號:
>>> ages = {'pam'=24}
File "<stdin>", line 1
ages = {'pam'=24}
^
SyntaxError: invalid syntax
同樣,此錯誤消息不是很有幫助。然而,重復的行和插入符號非常有幫助!他們直指問題人物。
如果您將 Python 語法與其他編程語言的語法混淆,則此類問題很常見。如果您將定義字典的行為與 dict() 調用混淆,您也會看到這一點。要解決此問題,您可以用冒號替換等號。您還可以切換到使用 dict():
>>> ages = dict(pam=24)
>>> ages
{'pam': 24}
其他編程語言使用花括號表示代碼塊,而 Python 使用空格。這意味著 Python 期望代碼中的空白行為可預測。如果代碼塊中的一行包含錯誤的空格數,它將引發 IndentationError:
def foo():
for i in range(10):
print(i)
print('done')
foo()
這可能很難看到,但第 5 行僅縮進了 2 個空格。應該和for循環語句一致,多4個空格。值得慶幸的是,Python 可以很容易地發現這一點,並會很快告訴您問題所在。
不過,這裡也有一些歧義。print('done') 行是在 for 循環之後還是在 for 循環塊內?當你運行上面的代碼時,你會看到以下錯誤:
File "indentation.py", line 5
print('done')
^
IndentationError: unindent does not match any outer indentation level
盡管回溯看起來很像 SyntaxError 回溯,但它實際上是一個 IndentationError。錯誤信息也很有幫助。它告訴您該行的縮進級別與任何其他縮進級別都不匹配。換句話說,print('done') 被縮進了 2 個空格,但是 Python 找不到任何其他符合這種縮進級別的代碼行。您可以通過確保代碼與預期的縮進級別對齊來快速解決此問題。
在定義或調用函數時,您可能會在 Python 中遇到無效語法。例如,如果在函數定義的末尾使用分號而不是冒號,則會看到 SyntaxError:
>>> def fun();
File "<stdin>", line 1
def fun();
^
SyntaxError: invalid syntax
這裡的回溯非常有用,插入符號直接指向問題字符。您可以通過將分號替換為冒號來清除 Python 中的這種無效語法。
此外,函數定義和函數調用中的關鍵字參數都需要按正確的順序排列。關鍵字參數總是在位置參數之後。不使用此順序將導致 SyntaxError:
>>> def fun(a, b):
... print(a, b)
...
>>> fun(a=1, 2)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
往期回顧
花 39 美金請AI畫家弄了個Logo
Deepfake 技術換臉真假難辨!
pandas常用的8個option設置!
7歲男童因下棋太快,被機器人夾斷手指?
分享
點收藏
點點贊
點在看