你一定遇到過Python學(xué)習(xí)中的無效語法,常見原因和解決辦法

前言

Python以其簡單的語法而聞名。然而瀑焦,當(dāng)您第一次學(xué)習(xí)Python時(shí)腌且,或者當(dāng)您具有另一種編程語言的堅(jiān)實(shí)背景時(shí),您可能會(huì)遇到一些Python不允許的事情榛瓮。如果您在嘗試運(yùn)行Python代碼時(shí)收到過SyntaxError錯(cuò)誤铺董,那么本指南可以幫助您。在本教程中禀晓,您將看到Python中常見的無效語法示例精续,并學(xué)習(xí)如何解決這個(gè)問題。

在本教程結(jié)束時(shí)粹懒,您將能夠:

識(shí)別Python中的無效語法

理解SyntaxError回溯

解析無效語法或完全阻止它

Python中的無效語法

當(dāng)您運(yùn)行Python代碼時(shí)重付,解釋器將首先解析它,將其轉(zhuǎn)換成Python字節(jié)碼凫乖,然后執(zhí)行确垫。解釋器將在程序執(zhí)行的第一階段(也稱為解析階段)中發(fā)現(xiàn)Python中的任何無效語法。如果解釋器不能成功地解析您的Python代碼帽芽,那么這意味著您在代碼的某個(gè)地方使用了無效的語法删掀。解釋器將嘗試向您顯示錯(cuò)誤發(fā)生的位置。

當(dāng)您第一次學(xué)習(xí)Python時(shí)导街,得到一個(gè)SyntaxError可能會(huì)令人沮喪爬迟。Python將嘗試幫助您確定無效語法在代碼中的位置,但是它提供的回溯可能會(huì)讓您感到有些困惑菊匿。有時(shí),它所指向的代碼是完全正確的计福。

您不能像處理其他異常一樣處理Python中的無效語法跌捆。即使您嘗試將try和except塊封裝到帶有無效語法的代碼中,您仍然會(huì)看到解釋器拋出一個(gè)SyntaxError象颖。

SyntaxError異常和回溯

當(dāng)解釋器在Python代碼中遇到無效語法時(shí)佩厚,它將拋出一個(gè)SyntaxError異常,并提供一個(gè)帶有一些有用信息的回溯说订,以幫助您調(diào)試錯(cuò)誤抄瓦。下面是一些Python中包含無效語法的代碼:

您可以在第4行字典的文字中看到無效的語法。第二個(gè)詞條“jim”漏掉了一個(gè)逗號(hào)陶冷。如果你試著按原樣運(yùn)行這段代碼钙姊,你會(huì)得到以下回溯結(jié)果:

注意,traceback消息定位的錯(cuò)誤在第5行埂伦,而不是第4行煞额。Python解釋器試圖指出無效語法的位置。然而,它只能指出它最初注意到的問題膊毁。當(dāng)您獲得一個(gè)SyntaxError traceback胀莹,并且traceback所指向的代碼看起來很好,那么您將希望開始向后移動(dòng)代碼婚温,直到您能夠確定哪里出了問題描焰。

在上面的例子中,根據(jù)后面的內(nèi)容栅螟,省略逗號(hào)是沒有問題的荆秦。例如,第5行“michael”后面缺少逗號(hào)是沒有問題的嵌巷。但是一旦解釋器遇到不理解的東西萄凤,它只能指出它發(fā)現(xiàn)的第一件不理解的事情。

有幾個(gè)元素的SyntaxError回溯搪哪,可以幫助您確定無效的語法在您的代碼:

遇到無效語法的文件名

遇到問題的行號(hào)和代碼的復(fù)寫行

在復(fù)制代碼下面的行中有一個(gè)插入符號(hào)(^)靡努,它向您顯示代碼中有問題的那一點(diǎn)

異常類型SyntaxError之后的錯(cuò)誤消息,可以提供幫助您確定問題的信息

在上面的例子中晓折,給出的文件名是theofficefacts惑朦。行號(hào)為5,插入符號(hào)指向字典鍵michael的結(jié)束引用漓概。SyntaxError回溯可能不會(huì)指向真正的問題漾月,但它將指向解釋器無法理解語法的第一個(gè)地方。

您可能會(huì)看到Python引發(fā)另外兩個(gè)異常胃珍。它們等價(jià)于SyntaxError梁肿,但有不同的名稱:

IndentationError

TabError

這些異常都繼承自SyntaxError類,但它們是涉及縮進(jìn)的特殊情況觅彰。當(dāng)代碼的縮進(jìn)級(jí)別不匹配時(shí)吩蔑,將引發(fā)IndentationError。當(dāng)代碼在同一文件中同時(shí)使用制表符和空格時(shí)填抬,將引發(fā)一個(gè)制表符錯(cuò)誤烛芬。在后面的小節(jié)中,您將進(jìn)一步了解這些異常飒责。

常見的語法問題

當(dāng)您第一次遇到SyntaxError時(shí)赘娄,了解為什么會(huì)出現(xiàn)問題以及如何修復(fù)Python代碼中的無效語法是很有幫助的。在下面的小節(jié)中宏蛉,您將看到可能引發(fā)SyntaxError的一些更常見的原因遣臼,以及如何修復(fù)它們。

1.誤用賦值運(yùn)算符(=)

在Python中有幾種情況下拾并,您不能對對象進(jìn)行賦值暑诸。一些例子是分配文字和函數(shù)調(diào)用蚌讼。在下面的代碼塊中,您可以看到一些嘗試這樣做的示例和由此產(chǎn)生的SyntaxError回溯:

Python作為一門不斷發(fā)展與普及的語言个榕,還在不斷更新中篡石。在學(xué)習(xí)時(shí),建議找一些學(xué)習(xí)伙伴一起來學(xué)習(xí)和討論西采,效果更佳凰萨。如果想學(xué)習(xí)Python,歡迎加入Python學(xué)習(xí)交流群(627012464)械馆,一起督促胖眷,一起學(xué)習(xí)。里面有開發(fā)工具霹崎,很多干貨和技術(shù)資料分享珊搀!

第一個(gè)示例嘗試將值5分配給len()調(diào)用。在這種情況下尾菇,SyntaxError消息非常有用境析。它告訴你不能給函數(shù)調(diào)用賦值。

第二個(gè)和第三個(gè)示例嘗試將字符串和整數(shù)分配給文字派诬。同樣的規(guī)則也適用于其他文字值劳淆。同樣,回溯消息表明默赂,當(dāng)您試圖將一個(gè)值賦給一個(gè)文字時(shí)沛鸵,問題就會(huì)發(fā)生。

很可能你的目的不是給文字或函數(shù)調(diào)用賦值缆八。例如曲掰,如果您不小心省略了額外的等號(hào)(=),就會(huì)發(fā)生這種情況奈辰,這會(huì)將賦值轉(zhuǎn)換為比較栏妖。如下所示,比較是有效的:

大多數(shù)情況下冯挎,當(dāng)Python告訴您正在對無法賦值的東西進(jìn)行賦值時(shí),您首先可能需要檢查以確保語句不應(yīng)該是布爾表達(dá)式咙鞍。當(dāng)您試圖為Python關(guān)鍵字賦值時(shí)房官,也可能遇到這個(gè)問題,下一節(jié)將討論這個(gè)問題续滋。

2.拼寫錯(cuò)誤翰守、缺少或誤用Python關(guān)鍵字

Python關(guān)鍵字是一組在Python中具有特殊含義的受保護(hù)的單詞。這些詞在代碼中不能用作標(biāo)識(shí)符疲酌、變量或函數(shù)名蜡峰。它們是語言的一部分了袁,只能在Python允許的上下文中使用。

有三種常見的方式湿颅,你可以錯(cuò)誤地使用關(guān)鍵字:

1.拼錯(cuò)的關(guān)鍵字

2.缺少一個(gè)關(guān)鍵字

3.濫用關(guān)鍵字

如果您在Python代碼中拼錯(cuò)了關(guān)鍵字载绿,那么您將得到一個(gè)SyntaxError。例如油航,如果你把關(guān)鍵字拼錯(cuò)了崭庸,會(huì)發(fā)生以下情況:

消息將讀取SyntaxError:無效語法,但這沒有多大幫助谊囚∨孪恚回溯指向Python可以檢測到錯(cuò)誤的第一個(gè)地方。要修復(fù)這類錯(cuò)誤镰踏,請確保所有Python關(guān)鍵字拼寫正確函筋。

另一個(gè)關(guān)于關(guān)鍵字的常見問題是你完全忽略了它們:

同樣,異常消息也不是很有用奠伪,但是回溯確實(shí)試圖為您指出正確的方向跌帐。如果從插入符號(hào)返回,則可以看到for循環(huán)語法中缺少關(guān)鍵字in芳来。

您還可能誤用受保護(hù)的Python關(guān)鍵字含末。記住,關(guān)鍵字只允許在特定的情況下使用即舌。如果您不正確地使用它們佣盒,那么您的Python代碼中就會(huì)出現(xiàn)無效的語法。一個(gè)常見的例子是在循環(huán)外使用continue或break顽聂。這在開發(fā)過程中很容易發(fā)生肥惭,當(dāng)你在實(shí)現(xiàn)一些東西的時(shí)候,碰巧把邏輯移出了一個(gè)循環(huán):

在這里紊搪,Python很好地告訴了您到底哪里出了問題蜜葱。"'break' outside loop"和" continue' not exactly in loop"這兩個(gè)信息可以幫助你明確地知道該怎么做。如果這段代碼在一個(gè)文件中耀石,那么Python也會(huì)讓插入符號(hào)指向被誤用的關(guān)鍵字牵囤。

另一個(gè)例子是,如果你嘗試給一個(gè)變量分配一個(gè)Python關(guān)鍵字滞伟,或者使用一個(gè)關(guān)鍵字來定義一個(gè)函數(shù):

當(dāng)您試圖為pass分配一個(gè)值時(shí)揭鳞,或者當(dāng)您試圖定義一個(gè)名為pass的新函數(shù)時(shí),您將得到一個(gè)SyntaxError并再次看到“無效語法”消息梆奈。

在Python代碼中解決這種類型的無效語法可能會(huì)稍微困難一些野崇,因?yàn)榇a從外部看起來沒什么問題。如果您的代碼看起來不錯(cuò)亩钟,但是您仍然會(huì)得到一個(gè)SyntaxError乓梨,那么您可以考慮檢查您想要使用的變量名或函數(shù)名與您正在使用的Python版本的關(guān)鍵字列表鳖轰。

受保護(hù)的關(guān)鍵字列表隨著Python的每個(gè)新版本而改變。例如扶镀,在Python 3.6中蕴侣,您可以使用await作為變量名或函數(shù)名,但是在Python 3.7中狈惫,這個(gè)單詞已經(jīng)被添加到關(guān)鍵字列表中【χ耄現(xiàn)在,如果您嘗試使用await作為變量名或函數(shù)名胧谈,如果您的代碼是Python 3.7或更高版本忆肾,那么這將導(dǎo)致SyntaxError。

另一個(gè)例子是print菱肖,它在python2和python3中有所不同:

print是python2中的一個(gè)關(guān)鍵字客冈,所以你不能給它賦值。然而稳强,在python3中场仲,它是一個(gè)可以賦值的內(nèi)置函數(shù)。

你可以運(yùn)行以下代碼來查看關(guān)鍵字列表退疫,無論你運(yùn)行的Python版本是什么:

keyword還提供了有用的keyword.iskeyword()渠缕。如果你只是需要一個(gè)快速的方法來檢查通過變量,那么你可以使用以下一行:

這段代碼將快速告訴您要使用的標(biāo)識(shí)符是否是關(guān)鍵字褒繁。

3.缺少括號(hào)亦鳞、方括號(hào)和引號(hào)

通常,Python代碼中無效語法的原因是缺少或不匹配的右括號(hào)棒坏、方括號(hào)或引號(hào)燕差。在嵌套圓括號(hào)的很長行或更長的多行塊中很難發(fā)現(xiàn)這些充岛。你可以通過Python的回溯來發(fā)現(xiàn)不匹配或缺失的引用:

這里弓乙,回溯指向無效代碼棍现,其中在結(jié)束單引號(hào)后有一個(gè)t'敬矩。要解決這個(gè)問題,您可以進(jìn)行以下兩種更改之一:

1.用反斜杠轉(zhuǎn)義單引號(hào)('don\t')

2.將整個(gè)字符串用雙引號(hào)括起來(“don't”)

另一個(gè)常見的錯(cuò)誤是忘記關(guān)閉字符串拴念。對于雙引號(hào)和單引號(hào)字符串宠漩,情況和回溯是相同的:

這一次蚂踊,traceback中的插入符號(hào)指向問題代碼磨澡。SyntaxError消息“在掃描字符串文字時(shí)的EOL”更具體一些碗啄,有助于確定問題。這意味著Python解釋器在一個(gè)開放字符串關(guān)閉之前到達(dá)該行(EOL)的末尾钱贯。要解決這個(gè)問題挫掏,請使用與開始時(shí)匹配的引號(hào)關(guān)閉字符串侦另。在本例中秩命,將使用雙引號(hào)(")尉共。

在f-string語句中缺少引號(hào)也會(huì)導(dǎo)致Python中無效的語法:

這里,打印的f-string中對ages字典的引用缺少關(guān)鍵引用的雙引號(hào)弃锐。得到的回溯結(jié)果如下:

Python識(shí)別問題并告訴您它存在于f-string中袄友。消息“未終止字符串”也指出了問題所在。本例中的插入符號(hào)僅指向f-string的開頭霹菊。

當(dāng)插入符號(hào)指向f-string的問題區(qū)域時(shí)剧蚣,這可能沒有那么有用,但是它確實(shí)縮小了您需要查找的范圍旋廷。在那個(gè)f字串的某個(gè)地方有一個(gè)未終止的字符串鸠按。你只需要找到在哪里。要修復(fù)此問題饶碘,請確保所有內(nèi)部f-string引號(hào)和方括號(hào)都已存在目尖。

缺少括號(hào)和方括號(hào)的情況大致相同。例如扎运,如果您從列表中刪除了右方括號(hào)瑟曲,那么Python將會(huì)發(fā)現(xiàn)并指出它。然而豪治,這有一些變化洞拨。第一種是把列表中的右括號(hào)去掉:

當(dāng)你運(yùn)行這段代碼時(shí),你會(huì)被告知調(diào)用print()有一個(gè)問題:

這里發(fā)生的是Python認(rèn)為列表包含三個(gè)元素:1负拟、2和3 print(foo())烦衣。Python使用空格從邏輯上對事物進(jìn)行分組,因?yàn)閺膒rint(foo())中沒有逗號(hào)或括號(hào)分隔3齿椅,所以Python將它們集中在一起作為列表的第三個(gè)元素琉挖。

另一種變化是在列表的最后一個(gè)元素后面添加一個(gè)逗號(hào),同時(shí)仍然去掉右方括號(hào):

現(xiàn)在你得到了一個(gè)不同的回溯:

在前面的例子中涣脚,3和print(foo())被集中在一起作為一個(gè)元素示辈,但是在這里你可以看到一個(gè)逗號(hào)將兩者分開。現(xiàn)在遣蚀,print(foo())的調(diào)用被添加為列表的第四個(gè)元素矾麻,Python到達(dá)了文件的末尾,但沒有使用右括號(hào)芭梯∠找回溯告訴您,Python已經(jīng)到達(dá)了文件(EOF)的末尾玖喘,但是它還在期待其他內(nèi)容甩牺。

在本例中,Python希望有一個(gè)右括號(hào)(])累奈,但是重復(fù)的行和插入符號(hào)沒有多大幫助贬派。缺少括號(hào)和方括號(hào)是Python很難識(shí)別的急但。有時(shí),您唯一能做的就是從插入符號(hào)開始搞乏,然后向后移動(dòng)波桩,直到您能夠識(shí)別出缺失或錯(cuò)誤的地方。

結(jié)論

在本教程中请敦,您已經(jīng)看到了SyntaxError回溯所提供的信息镐躲。您還看到了Python中許多常見的無效語法示例,以及這些問題的解決方案侍筛。這不僅會(huì)加快你的工作流程萤皂,而且還會(huì)使你成為一個(gè)更有幫助的代碼審查者!

在編寫代碼時(shí),請嘗試使用能夠理解Python語法并提供反饋的IDE匣椰。如果您將本教程中的許多無效Python代碼示例放到一個(gè)良好的IDE中敌蚜,那么它們應(yīng)該在您執(zhí)行代碼之前突出顯示問題行。

在學(xué)習(xí)Python時(shí)獲得一個(gè)SyntaxError可能會(huì)令人沮喪窝爪,但是現(xiàn)在您知道了如何理解回溯消息以及在Python中可能遇到的無效語法形式弛车。下一次出現(xiàn)SyntaxError時(shí),您就可以更好地快速修復(fù)這個(gè)問題了!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蒲每,一起剝皮案震驚了整個(gè)濱河市纷跛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌邀杏,老刑警劉巖贫奠,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異望蜡,居然都是意外死亡唤崭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門脖律,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谢肾,“玉大人,你說我怎么就攤上這事小泉÷瑁” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵微姊,是天一觀的道長酸茴。 經(jīng)常有香客問我,道長兢交,這世上最難降的妖魔是什么薪捍? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上酪穿,老公的妹妹穿的比我還像新娘与倡。我一直安慰自己,他們只是感情好昆稿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著息拜,像睡著了一般溉潭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上少欺,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天喳瓣,我揣著相機(jī)與錄音,去河邊找鬼赞别。 笑死畏陕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的仿滔。 我是一名探鬼主播惠毁,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼崎页!你這毒婦竟也來了鞠绰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤飒焦,失蹤者是張志新(化名)和其女友劉穎蜈膨,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牺荠,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡翁巍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了休雌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灶壶。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖杈曲,靈堂內(nèi)的尸體忽然破棺而出例朱,到底是詐尸還是另有隱情,我是刑警寧澤鱼蝉,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布洒嗤,位于F島的核電站,受9級(jí)特大地震影響魁亦,放射性物質(zhì)發(fā)生泄漏渔隶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望间唉。 院中可真熱鬧绞灼,春花似錦、人聲如沸呈野。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽被冒。三九已至军掂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昨悼,已是汗流浹背蝗锥。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留率触,地道東北人终议。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像葱蝗,于是被迫代替她去往敵國和親穴张。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容