《笨辦法學 python3》系列練習計劃——15.讀取文件

題目

本題本題開始涉及文件的操作,文件操作是一件危險的事情,需要仔細細心否則可能導致重要的文件損壞。

本題除了 ex15.py 這個腳本以外,還需要一個用來讀取的文件 ex15_sample.txt 其內容如下:

This is stuff I typed into a file.
It is really cool stuff.
Lots and lots of fun to have in here.

我們需要用 python 腳本打開文件並打印出來,不過我們不能把 ex15_sample.txt 寫死在腳本中,而是要利用之前聯繫過的 argvinput 從用戶那裏得知要處理的文件名。

加分練習

本題的難度跨度略大,因此 Zed 建議我們盡力做好加分練習後再做後面的練習。

  1. 在每行上面加註釋說明用途。
  2. 如果不確定答案,就找人問問,或者利用搜索(比如 “python open”)
  3. Zed 在本題中用了了”命令“這個詞,其實它們是“函數”和“方法”,去試着瞭解它們。
  4. 刪除 16-24 行(以我的答案)用到的 input 部分,再次運行一遍腳本。
  5. 只用 input 寫這個腳本,思考那種得到文件名的方法更好?爲什麼?
  6. 運行 pydoc file 找到 read() 命令(函數/方法),會看到很多別的命令,找幾條試試。不需要看 __(雙下劃線)的命令,這些只是垃圾而已(?)
  7. 再次運行 python 命令行,在命令行下使用 open 打開文件,這種 open 和 read 的方法值得也學習一下。
  8. 讓腳本針對 txttxt_again 變量執行一下 close(),處理完成的文件需要關閉,這點很重要。




我的答案

15.0 基礎練習 + 15.1 註釋

# 載入 sys.argv 模塊,以獲取腳本運行參數。
from sys import argv

# 將 argv 解包,並將腳本名賦值給變量 script ;將參數賦值給變量 filename 。
script, filename = argv

# 將名爲 “filename” 的文件打開,並將打開的內容賦值給變量 txt
txt = open(filename)

# 打印文件名,並在讀取文件內容後打印
print("Here's youer file %r:" % filename)
print(txt.read())

# ------------上面是通過 argv 獲取文件名--------

# 以 input 方式讓用戶在腳本運行後輸入文件名 
print("Type the filename again:")
file_again = input("> ")

# 打開用戶輸入的文件
txt_again = open(file_again)

# 讀取後打印用戶輸入文件的內容
print(txt_again.read())

這裏寫圖片描述

1-6 行使用 argv 我們相對都比較熟悉了。
open 是一個新的東西,我們可以通過 pydoc open 查看它的說明,恰巧發現有“友猿”整理了一部分 open 中文版文檔 少做排版、補充如下:

open(file, mode=’r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

(在使用該函數的時候,除了file參數必填外,其他參數可以選用。在本代碼中對其他參數使用了默認值。)

在使用 open() 的時候,如果文件不存在,那麼將會返回 IOError。

參數說明:
file:文件名稱;
mode:制定了文件打開的方式,函數提供瞭如下方式,其中,’rt’爲默認方式。

mode參數 解釋 中文 指針位置
'r' open for reading (default) 只讀,默認方式 開頭
'w' open for writing, truncating the file first 寫入,會覆蓋源文件內容 開頭
'x' create a new file and open it for writing 創建新文件,並寫入內容,如果文件已存在,將會報錯:FileExistsError 開頭
'a' open for writing, appending to the end of the file if it exists 寫入,如果文件有內容,則在末尾追加寫入 末尾
'b' binary mode 二進制模式
't' text mode (default) 文本模式
'+' open a disk file for updating (reading and writing) 更新磁盤文件,讀寫
'U' universal newline mode (deprecated) 在paython3中已經棄用

buffering:用於設置緩存策略
在二進制模式下,使用0來切換緩衝;在文本模式下,通過1表示行緩衝(固定大小的緩衝區)。
在不給參數的時候,二進制文件的緩衝區大小由底層設備決定,可以通過io.DEFAULT_BUFFER_SIZE獲取,通常爲4096或8192字節
文本文件則採用行緩衝。

encoding:編碼或者解碼方式。默認編碼方式依賴平臺,如果需要特殊設置,可以參考codecs模塊,獲取編碼列表。
errors:可選,並且不能用於二進制模式,指定了編碼錯誤的處理方式,可以通過codecs.Codec獲得編碼錯誤字符串
newline:換行控制(僅適用於文本模式),參數有:None,’\n’,’\r’,’\r\n’。
輸入時,如果參數爲None,那麼行結束的標誌可以是:’\n’,’\r’,’\r\n’任意一個,並且三個控制符都首先會被轉化爲:’\n’,然後纔會被調用;
如果參數爲'',所有的通用的換行結束標誌都可以用,但是行結束標識符返回調用不會被編碼。
輸出時,如果參數爲None,那麼行結束的標誌可以是:’\n’被轉換爲系統默認的分隔符;如果是”,’\n’則不會被編碼。

如果closefd = False,則在文件關閉時,底層文件描述符將保持打開狀態。 這在給定文件名時不起作用,在這種情況下必須爲True。
opener:可以通過調用*opener*方式,使用自定義的開啓器。底層文件描述符是通過調用*opener*或者*file*, *flags*獲得的。
*opener*必須返回一個打開的文件描述。將os.open作爲*opener*的結果,在功能上,類似於通過None。

===以下來自谷歌機翻===
open() 返回一個文件對象,其類型取決於模式,並通過它執行標準文件操作,如讀和寫。
當使用 open() 以文本模式(’w’,’r’,’wt’,’rt’等)打開文件時,它將返回一個TextIOWrapper。 當用於以二進制模式打開文件時,返回的類會有所不同:在讀取二進制模式下,它將返回一個BufferedReader; 在寫入二進制文件和追加二進制模式時,它返回一個BufferedWriter,並且在讀/寫模式下,它返回一個BufferedRandom。

也可以使用字符串或字節陣列作爲讀取和寫入的文件。 對於字符串StringIO可以像在文本模式下打開的文件一樣使用,對於字節,可以使用BytesIO就像以二進制模式打開的文件一樣。

我們把 open 打開的文件賦值給了變量 txt

接着在打印了一句話後,在第 12 行我們在 txt 這個被 open 打開的 file (“文件”類型)類型的變量上使用英文句號 . 調用了一個命令 read,並且麼有在括號中傳遞任何參數。

句點 A.B 是 python 常用的調用函數或方法,其意義相當於調用 A 下擁有的 B 方法。所有在本題的意思大概就是說“嘿 txt!你有一個‘方法’是 read吧?執行它,不需要任何參數”。

15.3 函數和方法

函數和方法是很相似的東西,因爲長的很像,所有有不少人覺得就是一個東西。
先來說一下各種語言都有的函數,函數是一組可以重複執行實現一個或一些功能的代碼。例如 print() 實現了把參數內容打印出來的功能,而且反覆執行功能維持不變。
方法則涉及類的概念,類中會有函數,實現類的一些功能,類的功能叫做類的方法。

15.4 刪除 input

我嘗試註釋掉了下面兩行都得到了 NameError 的錯誤,我不知道 Zed 這題想幹嘛。

file_again = input("> ")
txt_again = open(file_again)

這裏寫圖片描述

15.5 那種方法獲得文件名更好?

首先要分情況,根據開發需要選擇。
單說本題,我認爲使用 input 兼容性更好打字更少,比如遇到有文件名有空格的時候。用參數需要爲文件名添加引號,防止程序誤認爲是兩個參數。

但是如果從程序執行速度來說 input 需要人工兩次錄入(執行一次,文件名一次)會增加程序運行時間。

15.6 運行 pydoc file

python3 中使用 pydoc file 已經報錯了,沒有這個東西。原因大致是 Py2 的時候使用的是 C 語言的 I/O 。而 Py3 使用了新的的 I/O 雖然常用的方法沒什麼變化,使用起來也沒什麼問題,但是背後實現的方法已經發生了變化沒有 file 這個類了。
Zed 的本意可能是讓我們學會看文檔,以及預習之後會用到的知識。本題是文件讀取,下一題則是文件讀寫,所有我們不妨先看看我們本題打開的這份文本文件的文檔。

額外內容 —— 查看當前變量的文檔

之前我有提到過一次,除了 pydoc 以外,還可以在命令行中使用 help() 這個方法來查看函數或方法的文檔:

# 打開文件 'ex15_sample.txt' 並賦值個 file
>>> file = open('ex15_sample.txt')
# 使用 help 查看 file 的文檔
>>> help(file)

這裏寫圖片描述

使用 help 後會看到大致如上的內容(部分截圖),介紹當前查看元素的幫助文檔,我們從第一行可以看到,在 Py3 環境下使用 open 打開的這個東西的幫助文檔,實際上是 TextIOWrapper 對象的幫助文檔。

而用同樣的方法在 Py2 環境下打開一個 txt 文檔看到的確實下面的。
這裏寫圖片描述
找到了嗎?它其實是一個 file 的對象,這樣難怪我們在 Py3 無法用 pydoc 查看 file 的幫助文檔了。

15.8 關閉文件

如果我們使用的是向文件寫入東西,如果不關閉的話,是無法保存的。因此在完成文件操作之後切記關閉文件:

# 關閉文件
txt.close()
txt_again.close()

不過還有一種自動關閉文件的方法,我估計後面會有。着急的自行搜索 with open




返回目錄

《笨辦法學 python3》系列練習計劃——目錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章