Python編程常見問題與解答

  • 2019 年 12 月 12 日
  • 筆記

1.問:Python程式碼運行速度和C語言相比,哪個更快?

答:一般來說,Python程式碼的運行速度比C語言的慢很多,但是如果充分運用內置函數、標準庫對象和函數式編程模式的話,運行速度會提高很多,可以接近C語言。

2.問:學習Python編程,用哪個開發環境更好一些呢?

答:目前來看,Anaconda3和PyCharm用的相對來說多一些。

3.問:在哪裡執行pip命令安裝Python擴展庫?為什麼在IDLE中執行會提示語法錯誤呢?

答:應該在命令提示符環境執行,不是在Python開發環境中執行。並且,最好切換到Python安裝目錄中的scripts子目錄中執行,在安裝了多個Python版本時這一點非常重要。

4.問:為什麼使用pip命令安裝擴展庫是提示「不是內部或外部命令,也不是可運行的程式或批處理文件」?

答:檢查系統環境變數path是否包含Python的安裝目錄以及scripts子目錄,如果不包含的話,添加進去,或者切換到Python安裝目錄的scripts子目錄中執行pip命令。

5.問:使用pip安裝擴展庫總是提示網路超時,該怎麼辦呢?

答:可以下載安裝包或whl文件離線安裝,或者指定中國源,不使用pip默認的國外源。

6.問:使用pip安裝擴展庫時失敗,提示需要安裝VC++,該怎麼辦呢?

答:如果是Windows系統的話,可以使用瀏覽器打開https://www.lfd.uci.edu/~gohlke/pythonlibs/下載合適版本的whl文件,然後離線安裝。

7.問:我在https://www.lfd.uci.edu/~gohlke/pythonlibs/下載的文件名太長了,為了打字方便就改成了很短的名字,結果不能用了,必須使用原來的文件名嗎?

答:是的,不能修改文件名,必須保持原來的名字。

8.問:使用pip安裝擴展庫時,明明提示已經安裝成功了,但是使用import導入時又提示沒有安裝該擴展庫,為什麼呢?

答:這樣的情況一般是因為安裝了多個Python版本。在一個版本下安裝的擴展庫不能在另一個版本中使用,需要分別進行安裝。

9.問:map對象不支援下標嗎?為什麼使用下標訪問其中的元素時提示「TypeError: 'map' object is not subscriptable」呢?

答:是的,map對象、enumerate對象、zip對象、filter對象、reversed對象和生成器對象這些具有惰性求值特點的對象都不支援使用整數下標訪問其中的元素。可以把這類對象轉換為列表、元組來一次性獲取其中的元素,或者使用for循環逐個遍歷其中的元素。

10.問:訪問列表中元素時,提示「IndexError: list index out of range」,這是什麼原因呢?

答:應該是下標指定的位置不存在,檢查下標是否有效。一個長度為L的列表,有效下標範圍是[-L, L-1]。

11.問:在我的程式碼中x是一個列表,我使用y=x.sort()語句把它排序後的結果賦值給y,然後使用y.index(3)查看3在y中的下標時,為什麼會提示「AttributeError: 'NoneType' object has no attribute 'index'」呢?

答:列表的sort()方法是原地排序,沒有返回值。在Python中,沒有返回值的方法,都認為返回空值None,而空值是沒有index()方法的。

12.問:我創建了一個集合,想在裡面加入一個列表作為元素,結果提示「TypeError: unhashable type: 'list'」,這是什麼意思呢?

答:在Python中,不可哈希(unhashable)和可變的意思是一樣的。整數、實數、複數、字元串、元組這些是不可變的,或者說是可哈希的。而列表、字典、集合是可變的,或者說是不可哈希的。字典的「鍵」和集合的元素都要求必須是不可變的,也就是可哈希的。

13.問:我調用函數時提示「TypeError: f() missing 2 required positional arguments: 'a' and 'b'」,該怎麼辦呢?

答:調用函數時,位置參數的數量必須符合函數定義,如果函數要求接收2個位置參數,那麼調用時也應傳遞2個位置實參。

14.問:運行程式碼時提示「SyntaxError: expected an indented block」,怎麼解決呢?

答:Python程式碼對縮進的要求非常嚴格,相同層次的程式碼必須具有同樣的縮進量。

15.問:運行程式碼時提示「AttributeError: 'list' object has no attribute 'add'」,為什麼呢?

答:列表對象沒有add()方法,集合才有add(),仔細檢查對象的類型。

16.問:我想刪除元組當中的一個元素,提示「TypeError: 'tuple' object doesn't support item deletion」,是什麼意思呢?

答:在Python中,元組和字元串這樣的容器類對象是不可變的,不支援其中元素的增加、修改和刪除操作。

17.問:我想使用下標訪問集合中的第一個元素,運行程式碼時提示「TypeError: 'set' object does not support indexing」,是因為集合不支援下標嗎?

答:是的。Python集合裡面的元素是無序的,不能使用下標訪問特定位置的元素。

18.問:我想使用切片操作修改列表中的部分元素,運行程式碼時提示「ValueError: attempt to assign sequence of size 1 to extended slice of size 3」,該怎麼辦呢?

答:使用切片操作修改列表中部分元素時,如果第三個數字step的值不等於1,那麼等號左側的切片長度和等號右側的列表長度必須一致。

19.問:已知x是一個字元,我想使用x+1得到下一個字元,為什麼提示「TypeError: can only concatenate str (not "int") to str」呢?

答:Python不支援字元和整數相加,如果想得到下一個字元,可以使用表達式chr(ord(x)+1)。

20.問:運行程式碼時提示「NameError: name 'value' is not defined」,怎麼辦呢?

答:根據提示資訊來看,是說變數value沒定義。很可能是拼寫錯誤,仔細檢查變數是否拼寫正確。

21.問:我的程式碼可以運行,但是結果不對,怎麼辦呢?

答:程式碼可以運行表示沒有語法錯誤,不代表沒有邏輯錯誤。遇到這種情況時,仔細檢查程式碼的邏輯和問題的要求是否一致,是否把>寫成>=了,或者忽略了range()函數返回的是左閉右開區間了,是不是把運算符**寫成*了,是不是程式碼縮進有錯誤。

22.問:明明記事本程式文件是存在的,為什麼會提示「FileNotFoundError: [WinError 2] 系統找不到指定的文件。: 'C:\Windowsnotepad.exe'」呢?

答:在這個路徑中,第二個反斜線和後面的字母n恰好組成轉義字元n,應該使用兩個反斜線或者使用原始字元串。

23.問:訪問文件時,提示「PermissionError: [WinError 5] 拒絕訪問。: 'test.txt'」,怎麼辦呢?

答:應該是文件具有「只讀」之類的特殊屬性,或者當前登錄的用戶帳號沒有許可權訪問該文件。

24.問:我機器上明明是有test.txt這個文件的,為什麼使用內置函數open()打開時提示文件不存在呢?

答:如果文件test.txt不在當前文件夾中,在打開或讀寫時必須指定完整路徑。

25.問:從「資源管理器」來看,我當前文件夾中明明有test.txt文件,但是使用內置函數open()打開時還是提示文件不存在,可能是哪裡錯了呢?

答:默認情況下,「資源管理器」會隱藏一些常見類型文件的擴展名,去掉這個隱藏,檢查一下文件的名字是不是test.txt.txt。

26.問:運行程式碼讀取文本文件內容時,提示「UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb5 in position 0: invalid start byte」,是什麼錯誤呢?

答:如果文件中包含中文字元,應使用正確的編碼格式打開,也就是明確使用內置函數open()的encoding參數指定編碼格式。如果不知道文件採用什麼編碼格式,可以使用記事本打開之後使用「另存為」功能保存成特定的編碼格式。

27.問:我已經使用「pip install docx」命令安裝了擴展庫docx,為什麼無法運行書上的程式碼操作Word文件呢?

答:操作Word文件的擴展庫名字叫python-docx,不是docx。另外要注意,擴展庫python-docx只能操作Word 2007或更新版本的文檔,不能處理Word 2003之前的文檔。

28.問:使用open()函數打開文件往裡寫入內容時,提示「TypeError: write() argument must be str, not bytes」,是什麼原因呢?

答:如果要寫入文本文件的話,可以使用'w'模式;如果寫入二進位文件的話,應該使用'wb'模式。

29.問:使用內置函數open()打開文件之後,只能按照順序從前往後讀取內容嗎?

答:也不是,如果需要讀取前面已經讀取過的內容,可以使用文件對象的seek()方法修改文件指針的位置。

30.問:我用字元串方法startwith()測試一個字元串是否以另一個字元串為前綴,怎麼會提示「AttributeError: 'str' object has no attribute 'startwith'」這樣的錯誤呢?

答:字元串沒有startwith()方法,應該是startswith()。同理,也沒有endwith()方法,而是endswith()。

31.問:表達式{1, 2, 3}<{1, 2, 4}的值怎麼會是False呢?

答:關係運算符作用於集合時,表示集合之間的包含關係。對於集合A和B,只有A是B的真子集時,A<B的值才是True。

32.問:兩個列表是怎麼比較大小的呢?

答:列表比較大小時,是從前往後依次比較其中的每個元素,直到得到明確的結論為止。以[1, 2, 3]和[1, 2, 4]為例,第一個元素相等,第二個元素也相等,第三個元素3<4,所以[1, 2, 3]<[1, 2, 4]。以[1, 2, 3, 4]和[1, 2, 3]為例,兩個列表中前三個元素是相等的,但第一個列表中還有多餘的元素,所以[1, 2, 3, 4]>[1, 2, 3]。以[4, 2, 1]和[3, 5, 1]為例,第一個元素4>3,此時可以直接得出結論[4, 2, 1]>[3, 5, 1],後面的元素不再比較。元組和字元串也使用同樣的方式比較大小。

33.問:程式中有個map對象,第一次使用是正常的,但是再使用時好像裡面就沒有元素了,這是怎麼回事呢?

答:map對象、enumerate對象、zip對象、filter對象、reversed對象和生成器對象這些具有惰性求值特點的對象,其中的元素只能使用一次,訪問過的元素無法再次訪問。

34.在IDLE中運行程式,提示錯誤「UnicodeEncodeError: 'UCS-2' codec can't encode characters in position 96-96: Non-BMP character not supported in Tk」,但是程式碼怎麼檢查都是對的,怎麼辦呢?

答:IDLE中有些字元無法正常輸出,換個開發環境,或者在命令提示符環境中運行程式就可以了