目錄
一、Python2升級Python3發生的錯誤
1、print 變成了 print()
2、raw_Input 變成了 input
3、整數及除法的問題
4、例外處理大升級
5、解決 “NameError: name 'xrange' is not definedw” 錯誤提示
6、解決“name 'reload' is not defined 和 AttributeError: module 'sys' has no att” 錯誤提示
7、解決”python unicode is not defined” 錯誤提示
8、解決 “AttributeError: 'diet' object has no attribute 'has_key' ”錯誤提示
9、解決“lmportError: No module named urllib2”錯誤提示
二、程式常見錯誤
1、解決 “IndentationError:excepted an indented bloc” 錯誤提示
2、解決“no module named XX"錯誤提示
3、解決“TypeError: 'tuple' object cannot be interpreted as an integer"錯誤提示
4、解決“lOError: File not open for writing” 錯誤提示
5、解決“SyntaxError:invalid syntax” 錯誤提示
6、解決“TypeError: 'str' object does not support item assignment”錯誤提示
7、解決 “TypeError: Can't convert 'int' object to str implicitly”錯誤提示
8、錯誤的使用類變數
9、錯誤地理解Python的作用域
Hello!你好呀,我是灰小猿,一個超會寫bug的程式猿!
前兩天總結了一篇關于Python基礎入門的文章“【全網力薦】堪稱最易學的Python基礎入門教程”,受到了很多小伙伴的點贊和支持,感興趣的小伙伴可以去看一下,但是同時也是有很多人留言或者私信我說,剛開始接觸基礎知識并不牢固,在編程的時候還是會遇到很多的問題,所以今天在這里和大家總結記錄一下Python開發中常見的錯誤排查及其解決方案,希望能對大家學習Python編程有所幫助,大家可以先收藏關注!之后遇到了慢慢解決!
在撰寫并除錯Python程式的程序中,總會遇到這樣或那樣的錯誤,其中絕大多數錯誤都是由于大家粗心或語法錯誤引起的,所以接下來我總結了常見的錯誤型別及其詳細講解和解決排查方案,
一、Python2升級Python3發生的錯誤
在當前Python開發中,Python有2.7和Python3.x兩個大的版本分支,2.7的版本是比較老一點的,可能在網路教程、教學檔案和出版圖書中有的是用Python2.7實作的,

但是現在的大部分Python開發已經使用了3.x的版本,所以當我們直接將Python 2.7代碼運行在Python 3.x環境中時, 可能會發生一些語法錯誤,接下來就總結一下,
1、print 變成了 print()
在Python2版本中,print是作為一個陳述句使用的,在 Python3版本中print,作為一個函式出現,下面通過兩段代碼來展示兩個版本的區別,
Python 2.x版本代碼如下:
>>>i = 1
>>>print ' Python * * is', 'number', i
Pythonis number 1
Python 3.x版本代碼如下:
>>>i = 1
>>>print (' Python * * is ', * number', i)
Pythonis number 1
也就是說,在Python 3版本中,所有的print內容必須用小括號括起來,
2、raw_Input 變成了 input
在Python 2版本中,輸入功能是通過raw_input實作的,而在Python 3版本中,是通過input實作的,下面來看 兩行代碼的區別:
name = input('What is your name?\n') #python3版本 的代碼
name = raw_input ("What is your name?\n") # python2 版本的代碼
3、整數及除法的問題
剛開始學習在撰寫Python程式時,特別是將Python2的程式在Python 3環境下運行時,很可能會遇到 “TypeError: 'float* object cannot be interpreted as an integer”錯誤,例如下面的代碼是在 Python 2 運行成功的:
batch = 200
for x in range(len(order_nos) / batch + 1):
# do something
其中,order_nos是訂單串列,而在Python 3環境下運行時會提“TypeError:'float' object cannot be interpreted as an integer”錯誤,意思是float型別不能解釋為int型別, 這是因為在Python 3中,int和long統一為int型別,int 表示任何精度的整數,在以前的Python 2版本中,如果引數是int或者是long的話,就會回傳相除后結果的向下取整(floor),而如果引數是float或者是complex的話,那么就會回傳相除后結果的一個恰當的近似,當使用int超過本地整數大小時,不會再導致OverflowError 例外,long型別在Python 3中已經消失,并且后綴L也已經棄用,
下面是兩個版本的除法對比:
1/2 #Python 2版本中的結果是0
1/2 #Python 3版本中結果是0.5,這樣比較合理
與之相對應的是,除法也發生了變化,Python 3中的“/”總是回傳一個浮點數,永遠表示向下除法,所以當涉及除法“/” 操作遇到 “TypeError: 'float' object cannot be interpreted as an integer"錯誤時,只需將“/”修改為 “//” 即可,
4、例外處理大升級
在Python 2程式中,捕獲例外的格式如下:
except Exception, identifier
在Python 3程式中,捕獲例外的格式如下:
except Exception as identifier
例如,下面是Python 2捕獲例外的演示代碼:
except ValueError, e: # Python 2處理單個例外
except (ValueError, TypeError), e: # Python 2處理 多個例外
而下面是Python 3捕獲例外的演示代碼:
except ValueError as e: # Python3處理單個例外
except (ValueError, TypeError) as e: # Python3處理多個例外
在Python 2程式中,拋出例外的格式如下:
raise Exception, args
在Python 3程式中,拋出例外的格式如下:
raise Exception(args)
例如,下面兩行代碼演示了兩種版本拋出例外的方法:
raise ValueError, e # Python 2 .x 的方法
raise ValueError(e) # Python 3.x 的方法
5、解決 “NameError: name 'xrange' is not definedw” 錯誤提示
這個錯誤也是版本問題,Python2使用的是xrange()函 數,在Python3版本被range()函式代替,所以在Python 3 程式中,只需將xrange修改為range即可解決這個問題,
6、解決“name 'reload' is not defined 和 AttributeError: module 'sys' has no att” 錯誤提示
在Python 3.6程式中不能直接使用reload,要想兼容 Python 2中的reload功能,需要加入如下所示的代碼:
import importlib
importlib.reload(sys)
7、解決”python unicode is not defined” 錯誤提示
在Python 3程式中經常會遇到"python unicode is not defined”錯誤提示,這是因為在Python 3中已經沒有了 Unicode型別,被全新的str型別所代替,而Python 2中原有的str型別,在Python 3中被bytes所代替,
8、解決 “AttributeError: 'diet' object has no attribute 'has_key' ”錯誤提示
例如,下面的報錯程序:
>>> d={}
>>> d.has_key('name')
Traceback (most recent call last):
File "<pyshell#l>", line 1, in <module>
d.has_key(1name')
AttributeError: * diet * obj ect has no attribute ' has_key *
這是因為在Python 3中已經舍棄了 has_key,修改方法 是用in來代替has_key,修改為:
>>> d={}
>>> 'name' in d
True
9、解決“lmportError: No module named urllib2”錯誤提示
在 Python 3 中 urllib2 已經被 urllib.request 替代,所以 解決方法是將urllib2修改為urllib.request,
二、程式常見錯誤
1、解決 “IndentationError:excepted an indented bloc” 錯誤提示
這是一個很多初學者經常會犯的錯誤,這個錯誤會讓人欲哭無淚!這個錯誤并不是語法錯誤的問題,而是用戶代碼書寫規范的問題,因為Python是一個對代碼縮進非常敏感的語言,個人認為這也是Python語言的一個缺陷哈,整個回圈結構可能是依靠縮進的形式來表示的,
剛開始學習最常見的錯誤就是混用Tab和Space鍵實作代碼縮進,這是很容易報錯的,而且肉眼很難分辨出來,雖然很多IDE編輯器可以選擇顯示空格,但是即便是這樣,也很難找到到底哪里有問題,所以建議小伙伴在程式中只使用Tab鍵實作代碼縮進,或者只使用Space鍵實作代碼縮進,

另外,上面的報錯還有一個原因經常遇到,就是無首行縮進,例如在撰寫if陳述句時在后面加冒號,如果直接換行, 好多代碼編輯器會自動首行縮進,但是有些代碼編輯器可能沒有這個功能,這時需要大家手動縮進,這最好養成習慣, 請大家不要連續敲幾次空格鍵,建議直接按一下Tab鍵就行了,
2、解決“no module named XX"錯誤提示
毫無疑問,這個錯誤可能是大家在學習和開發程序中遇到的最多的錯誤,沒有之一,隨著大家開發水平的提高和程式復雜性的提升,將會在程式中用到越來越多的模塊和第三方庫,那時候將會經常遇到“no module named XX” 錯誤,這個錯誤的原因是沒有安裝庫“XX”,當遇到這個錯誤的時候,需要使用如下命令安裝庫XX:
pip install ww

3、解決“TypeError: 'tuple' object cannot be interpreted as an integer"錯誤提示
請看下面的代碼:
t=('a','b','c')
for i in range(t):
print (t [i])
上述代碼會報錯:TypeError: 'tuple* object cannot be interpreted as an integer
這是一個典型的型別錯誤問題,在上述代碼中,rangeO 函式期望的傳入引數是整型(integer),其但是卻傳入的參為元組(tuple) ,解決方法是將入參元組t改為元組個數 整型len(t)型別即可,例如將上述代碼中的range(t)改為 range(len(t)),
4、解決“lOError: File not open for writing” 錯誤提示
這是一個典型的檔案操作權限問題,例如下面的演示代碼會爆出這個錯誤:
>>> f=open ("hello. py")
>>> f.write ("test")
Traceback (most recent call last):
File "<stdin>n" line 1, in <module>
lOError:File not open for writing
出錯原因是在沒有在open("hello.py")的傳入引數中添加讀寫模式引數mode,這說明默認打開檔案的方式為只讀方式,而在上述代碼中需要寫入字符操作功能,所以出現 權限受限問題,才會報錯,解決方法是更改模式mode,修改為寫入模式權限w+:
f = open("hello. py", "w+")
f. write("test")
5、解決“SyntaxError:invalid syntax” 錯誤提示
這個錯誤通常是由于忘記在if、elif、else、for、while、 class和def等陳述句末尾添加冒號引起的,例如:
if spam == 42 print("Hello!")
解決方法是在最后添加冒號“:”.
還有一種情況也會引發上述錯誤,錯誤的使用了“=”而不是“==”,在Python程式中,“=”是賦值運算子,而“==”是等于比較操作,
6、解決“TypeError: 'str' object does not support item assignment”錯誤提示
這個錯誤通常是由于嘗試修改string的值引起的,string 是一種不可變的資料型別,例如在如下代碼中會發生該 錯誤:
spam = 'I have a pet cat'
spam[13] = 'r'
print(spam)
修改方法是:
spam = 'I have a pet cat.'
spam = spam[:13] + 'r' + spam[14:]
print(spam)
7、解決 “TypeError: Can't convert 'int' object to str implicitly”錯誤提示
這個錯誤通常是由于嘗試連接非字串值與字串引 起的,例如在如下代碼中會發生該錯誤:
numEggs = 12
print('I have ' + numEggs + "eggs.")
解決方法是修改為:
numEggs = 12
print("i have "+ str(numEggs) + " eggs.")
也可以修改為:
numEggs = 12
print('I have %s eggs.' % (numEggs))
8、錯誤的使用類變數
考慮下面的演示程序:
class A (object):
x = 1
class B (A):
pass
class C (A):
pass
print (A.x, B.x, C.x)
# 1 1 1
B.x = 2
print (A.x, B.x, C.x)
# 1 2 1
A.x = 3
print (A.x, B.x, C.x)
# 3 2 3
我們只修改了 A.x,為什么C.x也被改了?在Python 程式中,類變數在內部當做字典來處理,其遵循常被參考的方法決議順序(MRO),所以在上面的代碼中,由于class C中的x屬性沒有找到,它會向上找它的基類(盡管Python 支持多重繼承,但上面的例子中只有A),換句話說,class C中沒有它自己的x屬性,其獨立于A,因此,C.x事實上 是A.x的參考,
9、錯誤地理解Python的作用域
Python是基于LEGB來進行作用于決議的,因此在開發中還有一些需要注意的地方,先看下面一段代碼:
x = 10
def foo ():
x += 1
print(x)
foo ()
Traceback (most recent call last):
File "D:/程式代碼/Python/QRcode_Make/test.py", line 5, in <module>
foo ()
File "D:/程式代碼/Python/QRcode_Make/test.py", line 3, in foo
x += 1
UnboundLocalError: local variable 'x' referenced before assignment
上述代碼出錯的原因是:區域變數x沒有初始值,外部變數X不能引入到內部,
再看下面串列操作的情況:
lst = [1,2,3] #給串列lst賦值
lst. append (4) #丄t后邊append—*個元素4
print(lst)
# [1, 2, 3, 4]
lst += [5] #兩個串列合并
print(lst)
# [1, 2, 3, 4, 5]
def fool():
lst.append(6) #函式會査找外部的:1st串列
fool ()
print(lst)
# [1, 2, 3, 4, 5, 6]
def foo2():
lst += [6] #合并串列時,不會査找外部串列,讓人有 些不可思議吧
foo2 ()
Traceback (most recent call last):
File "D:/程式代碼/Python/QRcode_Make/test.py", line 26, in <module>
foo2 ()
File "D:/程式代碼/Python/QRcode_Make/test.py", line 24, in foo2
lst += [6] #合并串列時,不會査找外部串列,讓人有 些不可思議吧
UnboundLocalError: local variable 'lst' referenced before assignment
上述代碼的出錯原因和前面的例子相同,小伙伴們看了可能就會有疑問了,為什么fool可以合并,而fool2就不能合并呢?
原因是因為:fool沒有對lst進行賦值操作,而fool2做了, 要知道,lst += [5]是lst = lst + [5]的縮寫,我們試圖對lst 進行賦值操作(Python把他當成了區域變數),此外,我們對lst進行的賦值操作是基于lst自身(這再一次被Python 當成了區域變數),但此時還未定義,因此出錯!所以在這里就需要格外區磁區域變數和外部變數的使用程序了,
在學習中有疑問或者不懂的地方歡迎小伙伴評論留言!
之后持續為大家更新更多關于Python的技術分享!
覺得有用的小伙伴記得點贊關注喲!
灰小猿陪你一起進步!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/277039.html
標籤:python
