1. 程式人生 > >Python花式錯誤集錦(長期更新)

Python花式錯誤集錦(長期更新)

留言 int 項目 add encoding ror 操作 pat oba

Python是一門靈活的,有意思的,用途廣泛的語言。近些年來,收到越來越多的重視。也有越來越多的人來學習這門語言。

於是,問題來了,對於初學者,往往在寫代碼的過程中,出現這樣或那樣的錯誤,導致程序運行報錯。這些錯誤或簡單,或復雜,或詭異,或神奇,要麽令人抓耳撓腮,要麽讓人惱羞成怒,要麽讓人難以忘懷。但是,在學習編程的過程中,就是這些錯誤讓我們成長,讓我們逐漸從采坑再爬坑的過程中,感受到編程的魅力。

到底有哪些錯誤呢,請看DE8UG給你帶來的"Python花式錯誤集錦",如果你遇到了Python開發中的錯誤,從本文搜索關鍵詞並得到解決,那是我的榮幸。

語法錯誤篇

縮進IndentationError

這是在復制粘貼代碼,或者不熟悉Python代碼結構時候,經常範的錯誤。Python中要求同一邏輯的代碼塊使用同樣的縮進(常用4個空格)。

看這段:

def test():
    a = 1
    b = 2
   return a + b

運行後,立馬報錯

  File "<ipython-input-1-515579e6247e>", line 4
    return a + b
                ^
IndentationError: unindent does not match any outer indentation level

解決方法,很簡單,把縮進調整為統一的4個空格就好。

標點符號SyntaxError

這裏情況就比較多了,常見的為

  • 冒號錯誤
  • 逗號錯誤
  • 小括號缺失或不匹配

來看看具體錯誤樣式

def test():
    pass

  File "<ipython-input-2-b5cadef232ad>", line 1
    def test():
              ^
SyntaxError: invalid character in identifier

print(1,2,3,4,5,6)
  File "<ipython-input-3-be45856da7c7>", line 1
    print(1,2,3,4,5,6)
                ^
SyntaxError: invalid character in identifier

def test_a(a):
    return a * 2

def test_b(b):
    return b + 3

def test_c(c):
    return c - 4

x = 5
test_c(test_b(test_a))

TypeError                                 Traceback (most recent call last)
<ipython-input-4-af8d9c054419> in <module>()
      9 
     10 x = 5
---> 11 test_c(test_b(test_a))

<ipython-input-4-af8d9c054419> in test_b(b)
      3 
      4 def test_b(b):
----> 5     return b + 3
      6 
      7 def test_c(c):

TypeError: unsupported operand type(s) for +: ‘function‘ and ‘int‘

# 還可能這樣
test_c(test_b(test_a())

  File "<ipython-input-5-eab78f53d59a>", line 11
    test_c(test_b(test_a())
                           ^
SyntaxError: unexpected EOF while parsing

修改方式很簡單,代碼裏的標點符號都是英文,出現語法錯誤好好檢查看看標點符號的寬度,我的簡單記法是中文的都比較胖,英文的都是瘦子。另外,對於括號的問題,首先是要英文,其次呢寫的時候,養成一種上來先把成對()寫好的習慣,然後再填內容。

變量應用篇

命名錯誤

最需要禁止的是使用Python自帶的關鍵詞來命名,比如list,dict等,會導致類型錯誤。

a = (2,5,8)
a_list = list(a)  # 第一次可以用list轉換
list = list(a)  # 如果把list當作變量名,會引起後續代碼再用list轉換時候報錯
b = (3,5,7)
b_list = list(b)
TypeError                                 Traceback (most recent call last)
<ipython-input-12-70adb4cffa4f> in <module>()
      1 b = (3,5,7)
----> 2 b_list = list(b)

TypeError: ‘list‘ object is not callable
2b = c
  File "<ipython-input-7-9b1de15aaa88>", line 1
    2b = c
     ^
SyntaxError: invalid syntax

a-2 = 1
  File "<ipython-input-8-ac5315177c02>", line 1
    a-2 = 1
           ^
SyntaxError: can‘t assign to operator

命名時候,建議使用下劃線_連字符,或者theName,或者TheName這種首字母大寫的駝峰法。
而且,不建議使用0(數字零)或者l(小寫的L)來命名,否則容易引起下面的使用錯誤。

使用錯誤

這裏最常見的是使用容易混淆的字母來命名,造成似乎用時候出錯,或者是使用時候完全用錯了變量。

name_l = ‘de8ug‘
print(name_1)
NameError                                 Traceback (most recent call last)
<ipython-input-13-cfee4c383b1a> in <module>()
      1 name_l = ‘de8ug‘
----> 2 print(name_1)

NameError: name ‘name_1‘ is not defined

name_0 = ‘de8ug‘
print(name_o)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-14-7b351863596a> in <module>()
      1 name_0 = ‘de8ug‘
----> 2 print(name_o)

name = ‘de8ug‘
print(f‘name‘)
print(f‘{de8ug}‘)
print(f‘{name}‘)
NameError                                 Traceback (most recent call last)
<ipython-input-17-22b546a709ce> in <module>()
      1 name = ‘de8ug‘
      2 print(f‘name‘)
----> 3 print(f‘{de8ug}‘)
      4 print(f‘{name}‘)

NameError: name ‘de8ug‘ is not defined

編碼錯誤篇

Python3中,最常見的編碼錯誤是在網絡應用中,有時候得到的數據是bytes,但是我們實際需要str,這時候就需要轉換編碼。

這裏需要註意bytes和str的轉換,其中 encoding=‘utf-8‘是默認的參數

name = "de8ug"
print(type(name))  # str
print(type(name.encode()))  # bytes, S.encode(encoding=‘utf-8‘, errors=‘strict‘) -> bytes

name = b"de8ug"
print(type(name))  # bytes
print(type(name.decode()))  # str, decode(encoding=‘utf-8‘, errors=‘strict‘) --> str

導入模塊篇

  • 沒有提前導入

這種情況經常發生在使用某些模塊的功能,但是py文件頭部忘記導入

json.loads(‘{"name":"de8ug", "city":"beijing"}‘)

NameError                                 Traceback (most recent call last)
<ipython-input-41-fd9b6a45da38> in <module>()
----> 1 json.loads(‘{"name":"de8ug", "city":"beijing"}‘)

NameError: name ‘json‘ is not defined

這種情況經常出現在學習某些新內容,學習(chao)完代碼開始運行時候,發現啥啥啥沒defined,這時候就需要去檢查是不是最開始沒有import的問題了。

當加入 import json後,可得到正確結果{‘name‘: ‘de8ug‘, ‘city‘: ‘beijing‘}

  • 運行py文件時候報錯ModuleNotFoundError: No module named ‘xxx‘

這種情況一般是,運行的那個py文件又需要導入自己定義的其他模塊,
但此時系統不知道哪些模塊的存在,解決辦法是在運行的第一個py文件頭部,添加如下代碼:
這種情況適用於有個project項目,裏面又bin,conf,app等目錄,當bin裏面的py文件又需要引入conf,app等目錄的模塊時候,需要讓系統本身知道project這目錄的存在,先有爺爺,然後才能有孫子啊。

import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

函數使用篇

  • 作用域問題

Python在函數中使用變量的時候,會按照LEGB(Local(本地),Enclosing(封閉),Global(全局),Built-in(內置))這種作用域的順序來查找變量。如果有賦值(給同名的變量)操作,需要確保當前作用域下已經有這個變量。因為這時候Python認為函數內部和外部有同名的變量,會把外部的屏蔽。

name = ‘de8ug‘
def say_name():
    print(f‘name is: {name}‘)

say_name()  # 這時候正常, name is: de8ug

name = ‘de8ug‘
def say_name():
    name = name.capitalize()  # 把名字大寫,並賦值給name
    print(f‘name is: {name}‘)

say_name()

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-37-05a0d34cba37> in <module>()
      4     print(f‘name is: {name}‘)
      5 
----> 6 say_name()

<ipython-input-37-05a0d34cba37> in say_name()
      1 name = ‘de8ug‘
      2 def say_name():
----> 3     name = name.capitalize()  # 把名字大寫,並賦值給name
      4     print(f‘name is: {name}‘)
      5 

UnboundLocalError: local variable ‘name‘ referenced before assignment
這時候提示錯誤,name作為局部變量,在賦值前被引用了。因為和外部變量同名,此時name.capitalize()引用name的時候,在函數內部還沒有name這個變量的具體內容,所以報錯。

修改方式:
直接引用外部變量,使用相應的方法,或者采用不同的變量名

print(f‘name is: {name.capitalize() }‘) #  直接打印
或
cap_name = name.capitalize()

類似的還有+=的時候,這時候相當於兩部操作,先=+,但,如果函數內部變量和函數外相同,就會出現類似上面的錯誤。你感受一下:

n = 10
def add():
    n += 8
    print(n)

add()
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-46-8215b717b8ed> in <module>()
      4     print(n)
      5 
----> 6 add()

<ipython-input-46-8215b717b8ed> in add()
      1 n = 10
      2 def add():
----> 3     n += 8
      4     print(n)
      5 

UnboundLocalError: local variable ‘n‘ referenced before assignment

小結

ok,最後我們總結一下,常見的錯誤有這麽幾種,

  • 語法錯誤
  • 變量應用
  • 編碼錯誤
  • 導入模塊
  • 函數作用域

你都犯過了嗎?

聊到最後,有沒有解決你學習Python的過程裏出現的一些錯誤呢?或者,你有沒有遇到過什麽有意思的錯誤呢?歡迎留言討論,一起聊聊。

(首發於公眾號<第8哥小竈時間>,轉載請註明出處)

Python花式錯誤集錦(長期更新)