文件是保存在計算機存儲設備上的一些信息或數據。你已經知道了一些不一樣的文件類型,好比你的音樂文件,視頻文件,文本文件。Python 給了你一些簡單的方式操縱文件。一般咱們把文件分爲兩類,文本文件和二進制文件。文本文件是簡單的文本,二進制文件包含了只有計算機可讀的二進制數據。python
with
語句lscpu
命令的實現咱們使用 open()
函數打開文件。它須要兩個參數,第一個參數是文件路徑或文件名,第二個是文件的打開模式。模式一般是下面這樣的:shell
"r"
,以只讀模式打開,你只能讀取文件但不能編輯/刪除文件的任何內容"w"
,以寫入模式打開,若是文件存在將會刪除裏面的全部內容,而後打開這個文件進行寫入"a"
,以追加模式代開,寫入到文件中的任何數據將自動添加到末尾默認的模式爲只讀模式,也就是說若是你不提供任何模式,open()
函數將會以只讀模式打開文件。咱們將實驗打開一個文件,不過要準備實驗材料:bash
$ wget http://labfile.oss.aliyuncs.com/courses/596/sample.txt
而後進入 Python3 打開這個文件。數據結構
>>> fobj = open("sample.txt") >>> fobj <open file 'sample.txt', mode 'r' at 0xb7f2d968>
打開文件後咱們應該老是關閉文件。咱們使用方法 close()
完成這個操做。函數
>>> fobj.close()
始終確保你顯式關閉每一個打開的文件,一旦它的工做完成你沒有任何理由保持打開文件。由於程序能打開的文件數量是有上限的。若是你超出了這個限制,沒有任何可靠的方法恢復,所以程序可能會崩潰。每一個打開的文件關聯的數據結構(文件描述符/句柄/文件鎖...)都要消耗一些主存資源。所以若是許多打開的文件沒用了你能夠結束大量的內存浪費,而且文件打開時始終存在數據損壞或丟失的可能性。學習
使用 read()
方法一次性讀取整個文件。測試
>>> fobj = open("sample.txt") >>> fobj.read() 'I love Python\nI love shiyanlou\n' >>> fobj.close()
若是你再一次調用 read()
,它會返回空字符串由於它已經讀取完整個文件。ui
read(size)
有一個可選的參數 size
,用於指定字符串長度。若是沒有指定 size
或者指定爲負數,就會讀取並返回整個文件。當文件大小爲當前機器內存兩倍時,就會產生問題。反之,會盡量按比較大的 size 讀取和返回數據。spa
readline()
能幫助你每次讀取文件的一行。命令行
>>> fobj = open("sample.txt") >>> fobj.readline() 'I love Python\n' >>> fobj.readline() 'I love shiyanlou\n' >>> fobj.close()
使用 readlines()
方法讀取全部行到一個列表中。
>>> fobj = open('sample.txt') >>> fobj.readlines() ['I love Python\n', 'I love shiyanlou\n'] >>> fobj.close()
你能夠循環遍歷文件對象來讀取文件中的每一行。
>>> fobj = open('sample.txt') >>> for x in fobj: ... print(x, end = '') ... I love Python I love shiyanlou >>> fobj.close()
讓咱們寫一個程序,這個程序接受用戶輸入的字符串做爲將要讀取的文件的文件名,而且在屏幕上打印文件內容。
#!/usr/bin/env python3 name = input("Enter the file name: ") fobj = open(name) print(fobj.read()) fobj.close()
運行程序:
$ ./test.py Enter the file name: sample.txt I love Python I love shiyanlou
讓咱們經過 write()
方法打開一個文件而後咱們隨便寫入一些文本。
>>> fobj = open("ircnicks.txt", 'w') >>> fobj.write('powerpork\n') >>> fobj.write('indrag\n') >>> fobj.write('mishti\n') >>> fobj.write('sankarshan') >>> fobj.close()
如今讀取咱們剛剛建立的文件。
>>> fobj = open('ircnicks.txt') >>> s = fobj.read() >>> fobj.close() >>> print(s) powerpork indrag mishti sankarshan
在這個例子裏咱們拷貝給定的文本文件到另外一個給定的文本文件。
#!/usr/bin/env python3 import sys if len(sys.argv) < 3: print("Wrong parameter") print("./copyfile.py file1 file2") sys.exit(1) f1 = open(sys.argv[1]) s = f1.read() f1.close() f2 = open(sys.argv[2], 'w') f2.write(s) f2.close()
運行程序:
你能夠看到咱們在這裏使用了一個新模塊 sys
。sys.argv
包含全部命令行參數。這個程序的功能徹底能夠使用 shell 的 cp
命令替代:在 cp
後首先輸入被拷貝的文件的文件名,而後輸入新文件名。
sys.argv
的第一個值是命令自身的名字,下面這個程序打印命令行參數。
#!/usr/bin/env python3 import sys print("First value", sys.argv[0]) print("All values") for i, x in enumerate(sys.argv): print(i, x)
運行程序:
$ ./argvtest.py Hi there First value ./argvtest.py All values 0 ./argvtest.py 1 Hi 2 there
這裏咱們用到了一個新函數 enumerate(iterableobject)
,在序列中循環時,索引位置和對應值能夠使用它同時獲得。
讓咱們試着編寫一個程序,對任意給定文本文件中的製表符、行、空格進行計數。
#!/usr/bin/env python3 import os import sys def parse_file(path): """ 分析給定文本文件,返回其空格、製表符、行的相關信息 :arg path: 要分析的文本文件的路徑 :return: 包含空格數、製表符數、行數的元組 """ fd = open(path) i = 0 spaces = 0 tabs = 0 for i,line in enumerate(fd): spaces += line.count(' ') tabs += line.count('\t') # 如今關閉打開的文件 fd.close() # 以元組形式返回結果 return spaces, tabs, i + 1 def main(path): """ 函數用於打印文件分析結果 :arg path: 要分析的文本文件的路徑 :return: 若文件存在則爲 True,不然 False """ if os.path.exists(path): spaces, tabs, lines = parse_file(path) print("Spaces {}. tabs {}. lines {}".format(spaces, tabs, lines)) return True else: return False if __name__ == '__main__': if len(sys.argv) > 1: main(sys.argv[1]) else: sys.exit(-1) sys.exit(0)
運行程序:
你能夠看到程序有兩個函數,main()
和 parse_file()
,parse_file
函數真正的分析文件並返回結果,而後在 main()
函數裏打印結果。經過分割代碼到一些更小的單元(函數)裏,能幫助咱們組織代碼庫而且也更容易爲函數編寫測試用例。
with
語句在實際狀況中,咱們應該嘗試使用 with
語句處理文件對象,它會文件用完後會自動關閉,就算髮生異常也不要緊。它是 try-finally 塊的簡寫:
>>> with open('sample.txt') as fobj: ... for line in fobj: ... print(line, end = '') ... I love Python I love shiyanlou
lscpu
命令在 Linux 下你能夠使用 lscpu
命令來查看當前電腦的 CPU 相關信息,以下圖:
實際上 lscpu
命令是讀取 /proc/cpuinfo
這個文件的信息並美化輸出,如今你能夠本身寫一個 Python 程序以只讀模式讀取 /proc/cpuinfo
這個文件,而後打印出來,這樣你就有本身的一個 Python 版本的 lscpu
命令了 :)
記得一行一行的讀取文本文件,不要一次性讀取整個文件,由於有時候你讀取的文件可能比可用內存還大。
本實驗咱們學習了文件的打開與讀寫,在讀寫完畢後必定要記得關閉文件,或者使用 with 語句也是極好的。在 Linux 中你還須要注意你操做的文件的權限。Linux 有一個思想是「一切皆文件」,這在實驗最後的 lscpu
的實現中獲得了體現。