简明 Python 教程学习笔记_7_文件操作(os、shutil、pathlib )
?
參考 :http://www.cnblogs.com/nulige/archive/2016/12/06/6037752.html
?
?
在很多時候,你會想要讓你的程序與用戶(可能是你自己)交互。你會從用戶那里得到輸入,然后打印一些結果。我們可以分別使用?raw_input?和?print?語句來完成這些功能。對于輸出,你也可以使用多種多樣的?str(字符串)類。例如,你能夠使用?rjust?方法來得到一個按一定寬度右對齊的字符串。利用?help(str)?獲得更多詳情。
另一個常用的 輸入/輸出 類型是處理文件。創建、讀和寫文件的能力是許多程序所必需的
?
?
文件
?
- 你可以通過創建一個 file類 的對象來打開一個文件,分別使用 file類 的 read、readline 或 write 方法來恰當地讀寫文件。
- 對文件的讀寫能力依賴于你在打開文件時指定的模式。
- 最后,當你完成對文件的操作的時候,你調用 close 方法來告訴 Python 我們完成了對文件的使用。
使用文件
poem = '''\ Programming is fun When the work is done if you wanna make your work also fun: use Python! '''''' Python2 中 file 是內建函數 Python3 中 移除了 file 函數,使用 open 函數替代 '''# f = file('poem.txt', 'w') f = open('poem.txt', 'w') # open for 'w'riting f.write(poem) # write text to file f.close() # close the filef = open('poem.txt') # if no mode is specified, 'r'ead mode is assumed by default while True:line = f.readline()if len(line) == 0: # Zero length indicates EOFbreakprint(line, end='')# Notice comma to avoid automatic newline added by Python f.close() # close the file首先,我們通過指明我們希望打開的文件和模式來創建一個?file?類的實例。模式可以為讀模式('r')、寫模式('w')或追加模式('a')。事實上還有多得多的模式可以使用,你可以使用?help(file)?來了解它們的詳情。
我們首先用寫模式打開文件,然后使用?file?類的?write?方法來寫文件,最后我們用?close?關閉這個文件。
接下來,我們再一次打開同一個文件來讀文件。如果我們沒有指定模式,讀模式會作為默認的模式。在一個循環中,我們使用?readline?方法讀文件的每一行。這個方法返回包括行末換行符的一個完整行。所以,當一個空的 字符串被返回的時候,即表示文件末已經到達了,于是我們停止循環。
注意,因為從文件讀到的內容已經以換行符結尾,所以我們在 print 語句上使用逗號來消除自動換行。最后,我們用?close?關閉這個文件。
?
?
序列化
?
python3 的 _pickle 模塊詳解:https://www.cnblogs.com/ranxf/p/7800179.html
python3 中 cPickle 模塊已經更名為 _pickle,所以在 python3 中導入時可以使用:import _pickle as cPickle
或者使用 pandas 里面的 cPickle:https://blog.csdn.net/sinat_36458870/article/details/73551210
Python 提供一個標準的模塊,稱為?pickle。使用它你可以在一個文件中儲存?任何Python對象,之后你又可以把它完整無缺地取出來。這被稱為 持久的儲存對象。
還有另一個模塊稱為 cPickle,它的功能和 pickle 模塊完全相同,只不過它是用C語言編寫的,因此要快得多( 比 pickle 快 1000 倍)。你可以使用它們中的任一個,而我們在這里將使用 cPickle 模塊。記住,我們把這兩個模塊都簡稱為 pickle 模塊。
存儲與存取
#!/usr/bin/python # Filename: pickling.py# import cPickle as p # python2 使用 cPickle 方法# python3中cPickle模塊已經更名為_pickle,所以在python3中導入時可以使用: import _pickle as p # python3 使用 cPickle 方法# import pickle as pshop_list_file = 'shop_list.data' # the name of the file where we will store the objectshop_list = ['apple', 'mango', 'carrot']# Write to the file f = open(shop_list_file, 'w') p.dump(shop_list, f) # dump the object to a file f.close()del shop_list # remove the shop_list# Read back from the storage f = open(shop_list_file) stored_list = p.load(f) print(stored_list)# 輸出 # $ python # pickling.py # ['apple', 'mango', 'carrot']首先,請注意我們使用了 import..as 語法。這是一種便利方法,以便于我們可以使用更短的模塊名稱。在這個例子中,它還讓我們能夠通過簡單地改變一行就切換到另一個模塊(cPickle或者pickle)!在程序的其余部分的時候,我們簡單地把這個模塊稱為p。為了在文件里儲存一個對象,首先以寫模式打開一個file對象,然后調用儲存器模塊的dump函數,把對象儲存到打開的文件中。這個過程稱為儲存 。接下來,我們使用pickle模塊的load函數的返回來取回對象。這個過程稱為 取儲存 。
?
?
pathlib --- 面向對象的文件系統路徑
?
pathlib?官方文檔:https://docs.python.org/zh-cn/3/library/pathlib.html
你應該使用 pathlib 替代 os.path:https://zhuanlan.zhihu.com/p/87940289
?
?
Python 文件 和 目錄 操作方法大全(含實例)
?
Python 獲取當前路徑:https://www.cnblogs.com/strongYaYa/p/5860401.html
?
import?os, sys
使用 sys.path[0]、sys.argv[0]、os.getcwd()、os.path.abspath(__file__)、os.path.realpath(__file__)
sys.path 是 Python 會去尋找模塊的搜索路徑列表。
sys.path[0] 和 sys.argv[0] 是一回事,因為 Python 會自動把 sys.argv[0] 加入sys.path。
如果你在 C:\test 目錄下執行 python getpath\getpath.py,那么 os.getcwd() 會輸出 "C:\test" ,sys.path[0] 會輸出 "C:\test\getpath" 。
如果你用 py2exe 模塊把 Python 腳本編譯為可執行文件,那么 sys.path[0] 的輸出還會變化:
如果把依賴庫用默認的方式打包為 zip 文件,那么 sys.path[0] 會輸出 "C:\test\getpath\libarary.zip";
如果在 setup.py 里面指定 zipfile=None 參數,依賴庫就會被打包到 exe 文件里面,那么 sys.path[0] 會輸出 "C:\test\getpath\getpath.exe"。
示例代碼:
#!/bin/env python # -*- encoding=utf8 -*-import os import sysif __name__ == "__main__":print("__file__=%s" % __file__)print("os.path.realpath(__file__)=%s" % os.path.realpath(__file__))print(f"os.path.dirname(os.path.realpath(__file__))={os.path.dirname(os.path.realpath(__file__))}")print(f"os.path.split(os.path.realpath(__file__))={os.path.split(os.path.realpath(__file__))[0]}")print("os.path.abspath(__file__)=%s" % os.path.abspath(__file__))print("os.getcwd()=%s" % os.getcwd())print("sys.path[0]=%s" % sys.path[0])print("sys.argv[0]=%s" % sys.argv[0])# 輸出結果: # D:\>python ./python_test/test_path.py # __file__=./python_test/test_path.py # os.path.realpath(__file__)=D:\python_test\test_path.py # os.path.dirname(os.path.realpath(__file__))=D:\python_test # os.path.split(os.path.realpath(__file__))=D:\python_test # os.path.abspath(__file__)=D:\python_test\test_path.py # os.getcwd()=D:\ # sys.path[0]=D:\python_test # sys.argv[0]=./python_test/test_path.py獲取當前的路徑:
import os import sysif __name__ == "__main__":# __file__ 是當前執行的文件# 獲取當前文件__file__的路徑print(f"os.path.realpath(__file__)= {os.path.realpath(__file__)}")# 獲取當前文件__file__的所在目錄print(f"os.path.dirname(os.path.realpath(__file__))= {os.path.dirname(os.path.realpath(__file__))}")# 獲取當前文件__file__的所在目錄print(f"os.path.split(os.path.realpath(__file__))= {os.path.split(os.path.realpath(__file__))[0]}")?
Python判斷文件是否存在的三種方法
:https://www.cnblogs.com/jhao/p/7243043.html
?
?
一、Python中對文件、文件夾操作(os 和 shutil 常用方法)
# os 模塊
os.sep?可以取代操作系統特定的路徑分隔符。windows下為 '\\' os.name?字符串指示你正在使用的平臺。比如對于Windows,它是'nt',而對于Linux/Unix用戶,它是 'posix' os.getcwd()?函數得到當前工作目錄,即當前Python腳本工作的目錄路徑 os.getenv()?獲取一個環境變量,如果沒有返回none os.putenv(key, value)?設置一個環境變量值 os.listdir(path)?返回指定目錄下的所有文件和目錄名 os.remove(path)?函數用來刪除一個文件 os.system(command)?函數用來運行shell命令 os.linesep?字符串給出當前平臺使用的行終止符。例如,Windows使用 '\r\n',Linux使用 '\n' 而Mac使用 '\r' os.path.split(path)??函數返回一個路徑的目錄名和文件名 os.path.isfile()?和os.path.isdir()函數分別檢驗給出的路徑是一個文件還是目錄 os.path.exists()?函數用來檢驗給出的路徑是否真地存在 os.curdir??返回當前目錄 ('.') os.mkdir(path)?創建一個目錄 os.makedirs(path)?遞歸的創建目錄 os.chdir(dirname)?改變工作目錄到dirname???? os.path.getsize(name)?獲得文件大小,如果name是目錄返回0L os.path.abspath(name)?獲得絕對路徑 os.path.normpath(path)?規范path字符串形式 os.path.splitext()??分離文件名與擴展名 os.path.join(path,name)?連接目錄與文件名或目錄 os.path.basename(path)?返回文件名 os.path.dirname(path)?返回文件路徑 os.walk(top,topdown=True,οnerrοr=None)??遍歷迭代目錄os.rename(src, dst)??重命名file或者directory src到dst 如果dst是一個存在的directory, 將拋出OSError. 在Unix, 如果dst存在且是一個file, 如果用戶 有權限的話,它將被安靜的替換. 操作將會失敗在某些Unix 中如果src和dst在不同的文件系統中. 如果成功, 這命名操作將會是一個原子操作 (這是POSIX 需要). 在 Windows上, 如果dst已經存在, 將拋出OSError,即使它是一個文件. 在unix,Windows中有效。os.renames(old, new)?遞歸重命名文件夾或者文件。像rename()# shutil 模塊
1.得到當前工作目錄,即當前Python腳本工作的目錄路徑: os.getcwd() 2.返回指定目錄下的所有文件和目錄名: os.listdir() 3.函數用來刪除一個文件: os.remove() 4.刪除多個目錄: os.removedirs(r“c:\python”) 5.檢驗給出的路徑是否是一個文件: os.path.isfile() 6.檢驗給出的路徑是否是一個目錄: os.path.isdir() 7.判斷是否是絕對路徑: os.path.isabs() 8.檢驗給出的路徑是否真地存: os.path.exists() 9.返回一個路徑的目錄名和文件名: os.path.split() eg os.path.split('/home/swaroop/byte/code/poem.txt') 結果:('/home/swaroop/byte/code', 'poem.txt') 10.分離擴展名: os.path.splitext() 11.獲取路徑名: os.path.dirname() 12.獲取文件名: os.path.basename() 13.運行shell命令: os.system() 14.讀取和設置環境變量:os.getenv() 與os.putenv() 15.給出當前平臺使用的行終止符: os.linesep Windows使用'\r\n',Linux使用'\n'而Mac使用'\r' 16.指示你正在使用的平臺: os.name 對于Windows,它是'nt',而對于Linux/Unix用戶,它是'posix' 17.重命名: os.rename(old, new) 18.創建多級目錄: os.makedirs(r“c:\python\test”) 19.創建單個目錄: os.mkdir(“test”) 20.獲取文件屬性: os.stat(file) 21.修改文件權限與時間戳:os.chmod(file) 22.終止當前進程: os.exit() 23.獲取文件大小: os.path.getsize(filename)shutil.copyfile( src, dst)?從源src復制到dst中去。當然前提是目標地址是具備可寫權限。拋出的異常信息為IOException. 如果當前的dst已存在的話就會被覆蓋掉 shutil.move( src, dst)??移動文件或重命名 shutil.copymode( src, dst)?只是會復制其權限其他的東西是不會被復制的 shutil.copystat( src, dst)?復制權限、最后訪問時間、最后修改時間 shutil.copy( src, dst)??復制一個文件到一個文件或一個目錄 shutil.copy2( src, dst)??在copy上的基礎上再復制文件最后訪問時間與修改時間也復制過來了,類似于cp –p的東西 shutil.copy2( src, dst)??如果兩個位置的文件系統是一樣的話相當于是rename操作,只是改名;如果是不在相同的文件系統的話就是做move操作 shutil.copytree( olddir, newdir, True/Flase)把olddir拷貝一份newdir,如果第3個參數是True,則復制目錄時將保持文件夾下的符號連接,如果第3個參數是False,則將在復制的目錄下生成物理副本來替代符號連接 shutil.rmtree( src )?遞歸刪除一個目錄以及目錄內的所有內容?
二、文件操作方法大全:
關于 open 模式:
r: 只讀模式,文件必須存在 w: 以寫方式打開, a: 以追加模式打開 (從 EOF 開始, 必要時創建新文件) r+:以讀寫模式打開。 讀寫模式,光標默認在起始位置,當需要寫入的時候,光標自動移到最后 w+:以讀寫模式打開 (參見 w ) 寫讀模式,先清空原內容,再寫入,也能夠讀取 a+:以讀寫模式打開 (參見 a ) 追加讀模式,光標默認在最后位置,直接寫入,也能夠讀取。 rb:以二進制讀模式打開 wb:以二進制寫模式打開 (參見 w ) ab:以二進制追加模式打開 (參見 a ) rb+:以二進制讀寫模式打開 (參見 r+ ) wb+:以二進制讀寫模式打開 (參見 w+ ) ab+:以二進制讀寫模式打開 (參見 a+ )文件操作:
os.mknod("test.txt") # 創建空文件 fp = open("test.txt", 'w') # 直接打開一個文件,如果文件不存在則創建文件fp.read([size]) # size為讀取的長度,以byte為單位 fp.readline([size]) # 讀一行,如果定義了size,有可能返回的只是一行的一部分 fp.readlines([size]) # 把文件每一行作為一個list的一個成員,并返回這個list。其實它的內部是通過循環調用readline()來實現的。如果提供size參數,size是表示讀取內容的總長,也就是說可能只讀到文件的一部分。 fp.write(str) # 把str寫到文件中,write()并不會在str后加上一個換行符 fp.writelines(seq) # 把seq的內容全部寫到文件中(多行一次性寫入)。這個函數也只是忠實地寫入,不會在每行后面加上任何東西。 fp.close() # 關閉文件。python會在一個文件不用后自動關閉文件,不過這一功能沒有保證,最好還是養成自己關閉的習慣。 # 如果一個文件在關閉后還對其進行操作會產生ValueError fp.flush() # 把緩沖區的內容寫入硬盤 fp.fileno() # 返回一個長整型的”文件標簽“ fp.isatty() # 文件是否是一個終端設備文件(unix系統中的) fp.tell() # 返回文件操作標記的當前位置,以文件的開頭為原點 fp.next() # 返回下一行,并將文件指針移到下一行。把一個file用于for … in file這樣的語句時,就是調用next()函數來實現遍歷的。 fp.seek(offset[,whence]) # 將文件打操作標記移到offset的位置。這個offset一般是相對于文件的開頭來計算的,一般為正數。如果提供whence參數就不一定了,whence為 0 表示從頭開始計算,1 表示以當前位置為原點計算。2 表示以文件末尾為原點進行計算。注意:如果文件以a或a+的模式打開,每次進行寫操作時,文件操作標記會自動返回到文件末尾。 fp.truncate([size]) # 把文件裁成規定的大小,默認的是裁到當前文件操作標記的位置。如果size比文件的大小還要大,依據系統的不同可能是不改變文件,也可能是用0把文件補到相應的大小,也可能是隨機內容加上去。注意:???把兩個路徑合成一個時,不要直接拼字符串,而要通過?os.path.join(part1,part2)函數,這樣可以正確處理不同操作系統的路徑分隔符。在linux/Unix/Mac下,os.path.join()返回這樣的字符串: part1/part2。而Windows下會返回這樣的字符串: part1\part2?
import os import shutilfile_dir = "D:\\Python_os\\os" # 注意 \\ ;windows 下是這么表示的;Linux 和 Mac 是 / file_name = "test.txt" file_abs = os.path.join(file_dir, file_name) # os.path.join(...) 表示路徑鏈接'''判斷路徑或文件''' print (1,os.path.isabs(file_dir)) # 判斷是否絕對路徑 print (2,os.path.isabs(file_name)) print (3,os.path.isabs(file_abs)) print (4,os.path.exists(file_abs)) # 判斷是否真實存在 print (5,os.path.exists(os.path.join(file_dir,"xxx"))) print (6,os.path.isdir(file_dir)) # 判斷是否是個目錄 print (7,os.path.isdir(file_abs)) print (8,os.path.isfile(file_dir)) # 判斷是否是個文件 print (9,os.path.isfile(file_abs)) 復制、移動文件夾/文件。須使用 shutil 模塊,引入 import shutil shutil.copyfile("old","new") # 復制文件,都只能是文件 shutil.copytree("old","new") # 復制文件夾,都只能是目錄,且new必須不存在 shutil.copy("old","new") # 復制文件/文件夾,復制 old 為 new(new是文件,若不存在,即新建),# 復制 old 為至 new 文件夾(文件夾已存在) shutil.move("old","new") # 移動文件/文件夾至 new 文件夾中import os import shutilfile_dir = "D:\\Python_shutil" os.chdir(file_dir) shutil.copyfile("test_org.txt","test_copy.txt") # copy test_org.txt 為 test_copy.txt 若存在,則覆蓋 shutil.copyfile("test_org.txt","test1.txt") # 存在,覆蓋 shutil.copytree("test_org","test_copytree") # copy test_org 為 test_copytree(不存在的新目錄) shutil.copy("test_org.txt","test_copy1.txt") # 同 copyfile shutil.copy("test_org.txt","test_copy") # 將文件 copy 至 目標文件夾中(須存在) shutil.copy("test_org.txt","test_xxx") # 將文件 copy 至 目標文件(該文件可不存在,注意類型!) print os.listdir(os.getcwd()) shutil.move("test_org.txt","test_move") # 將文件 move 至 目標文件夾中 shutil.move("test_org","test_move") # 將文件夾 move 至 目標文件夾中 print os.listdir(os.getcwd())?
三、目錄操作方法大全
?
1.創建目錄os.mkdir("file") 2.復制文件:shutil.copyfile("oldfile","newfile") #oldfile和newfile都只能是文件 shutil.copy("oldfile","newfile") #oldfile只能是文件夾,newfile可以是文件,也可以是目標目錄 3.復制文件夾: 4.shutil.copytree("olddir","newdir") #olddir和newdir都只能是目錄,且newdir必須不存在 5.重命名文件(目錄) os.rename("oldname","newname") #文件或目錄都是使用這條命令 6.移動文件(目錄) shutil.move("oldpos","newpos") 7.刪除文件 os.remove("file") 8.刪除目錄 os.rmdir("dir") #只能刪除空目錄 shutil.rmtree("dir") #空目錄、有內容的目錄都可以刪 9.轉換目錄 os.chdir("path") #換路徑os.getcwd() # 獲取當前工作目錄 os.chdir(...) # 改變工作目錄 os.listdir(...) # 列出目錄下的文件 os.mkdir(...) # 創建單個目錄 注意:創建多級用 os.makedirs() os.makedirs(...) # 創建多級目錄?
四、文件綜合操作實例
?
將文件夾下所有圖片名稱加上 '_fc'
# -*- coding:utf-8 -*- import re import os import time #str.split(string)分割字符串 #'連接符'.join(list) 將列表組成字符串 def change_name(path):global iif not os.path.isdir(path) and not os.path.isfile(path):return Falseif os.path.isfile(path):file_path = os.path.split(path) #分割出目錄與文件lists = file_path[1].split('.') #分割出文件與文件擴展名file_ext = lists[-1] #取出后綴名(列表切片操作)img_ext = ['bmp','jpeg','gif','psd','png','jpg']if file_ext in img_ext:os.rename(path,file_path[0]+'/'+lists[0]+'_fc.'+file_ext)i+=1 #注意這里的i是一個陷阱#或者#img_ext = 'bmp|jpeg|gif|psd|png|jpg'#if file_ext in img_ext:# print('ok---'+file_ext)elif os.path.isdir(path):for x in os.listdir(path):change_name(os.path.join(path,x)) #os.path.join()在路徑處理上很有用 img_dir = 'D:\\xx\\xx\\images' img_dir = img_dir.replace('\\','/') start = time.time() i = 0 change_name(img_dir) c = time.time() - start print('程序運行耗時:%0.2f'%(c)) print('總共處理了 %s 張圖片'%(i))輸出結果: 程序運行耗時:0.11 總共處理了 109 張圖片?
?
文件操作_讀寫函數詳解
?
file() 函數用于創建一個file對象,它有一個別名叫open(),可能更形象一些,它們是內置函數。
file(name[, mode[, buffering]]) -> file object Open a file. The mode can be ‘r’, ‘w’ or ‘a’ for reading (default),writing or appending. The file will be created if it doesn’t exist when opened for writing or appending; it will be truncated when opened for writing. Add a ‘b’ to the mode for binary files. Add a ‘+’ to the mode to allow simultaneous reading and writing. If the buffering argument is given, 0 means unbuffered, 1 means line buffered, and larger numbers specify the buffer size. The preferred way to open a file is with the builtin open() function. Add a ‘U’ to mode to open the file for input with universal newline support. Any line ending in the input file will be seen as a ‘\n’ in Python. Also, a file so opened gains the attribute ‘newlines’; the value for this attribute is one of None (no newline read yet), ‘\r’, ‘\n’, ‘\r\n’ or a tuple containing all the newline types seen. ‘U’ cannot be combined with ‘w’ or ‘+’ mode. file()與open()的功能一致,打開文件或創建文件。都屬于內建函數。file的屬性和方法:
In [1]: dir(file) Out[1]: ['__class__','__delattr__','__doc__','__enter__','__exit__','__format__','__getattribute__','__hash__','__init__','__iter__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','close','closed','encoding','errors','fileno','flush','isatty','mode','name','newlines','next','read','readinto','readline','readlines','seek','softspace','tell','truncate','write','writelines','xreadlines']在 Python 中一切皆對象,file 也不例外,file 也有方法和屬性。
下面先來看如何創建一個file對象:file(name[, mode[, buffering]])?
buffering 如果為 0 表示不進行緩沖,如果為 1 表示進行 "行緩沖",如果是一個大于 1 的數表示緩沖區的大小,應該是以字節為單位的。
file 對象的屬性和方法。
file的屬性:closed # 標記文件是否已經關閉,由close()改寫 encoding # 文件編碼 mode # 打開模式 name # 文件名 newlines # 文件中用到的換行模式,是一個tuple softspace # boolean型,一般為0,據說用于printfile的讀寫方法:F.read([size]) # size為讀取的長度,以byte為單位 F.readline([size]) # 讀一行,如果定義了size,有可能返回的只是一行的一部分 F.readlines([size]) # 把文件每一行作為一個list的一個成員,并返回這個list。其實它的內部是通過循環調用 readline() 來實現的。如果提供size參數,size是表示讀取內容的總長,也就是說可能只讀到文件的一部分。 F.write(str) # 把str寫到文件中,write()并不會在str后加上一個換行符 F.writelines(seq) # 把seq的內容全部寫到文件中。這個函數也只是忠實地寫入,不會在每行后面加上任何東西。 F.close() # 關閉文件。如果一個文件在關閉后還對其進行操作會產生ValueErrorF.flush() # 把緩沖區的內容寫入硬盤 F.fileno() # 返回一個長整型的 "文件描述符",即 "文件句柄" 或者 id F.isatty() # 文件是否是一個終端設備文件(unix系統中的) F.tell() # 返回文件操作標記的當前位置,以文件的開頭為原點 F.next() # 返回下一行,并將文件操作標記位移到下一行。把一個file用于for ... in file這樣的語句時,就是調用next()函數來實現遍歷的。 F.seek(offset[,whence]) # 將文件打操作標記移到offset的位置。這個offset一般是相對于文件的開頭來計算的,一般為正數。# 但如果提供了whence參數就不一定了,whence可以為0表示從頭開始計算,1表示以當前位置為原點計算。2表示以文件末尾為原點進行計算。# 需要注意,如果文件以a或a+的模式打開,每次進行寫操作時,文件操作標記會自動返回到文件末尾。 F.truncate([size]) # 把文件裁成規定的大小,默認的是裁到當前文件操作標記的位置。# 如果size比文件的大小還要大,依據系統的不同可能是不改變文件,# 也可能是用0把文件補到相應的大小,也可能是以一些隨機的內容加上去。?
open()文件操作
open(…) open(name[, mode[, buffering]]) -> file object Open a file using the file() type, returns a file object. This is the preferred way to open a file. See file.__doc__ for further information. open()函數是file()函數的別名函數,能夠打開文件并返回一個文件對象而非文件的內容。 (應該理解為一個存儲著文件的內容的對象,如果想獲取內容便需要對文件對象進行操作)。 可以指定不同的打開mode(rw),在調用open()函數后一定要調用文件對象內建的close()函數來關閉文件。 一般結合try..finally語句來確定會關閉文件對象。 注意:當你open()一個文件,實質上是將該文件的內容加載到緩存中,所以當你open()文件之后,對文件做了修改也不會影響到open()返回的對象的value。常用mode ( 6 種mode可以組合使用):?
r(read缺省參數): 以讀的方式打開文件,不能調用write方法,當文件不存在時報錯。 w(write): 以寫方式打開文件,能夠寫入內容并覆蓋,不能調用read方法, 如果文件不存在,則創建新同名文件。 a(append): 以追加模式打開文件,可以進行寫操作, 如果文件不存在,則創建新同名文件。 +: 使用+允許同時進行讀寫操作。 U: 支持所有類型的換行符(\n、\r、\r\n) 。由于歷史的原因,換行符在不同的系統中有不同模式,比如在 unix中是一個\n,而在windows中是‘\r\n’,用U模式打開文件,就是支持所有的換行模式,也就說‘\r’ '\n' '\r\n'都可表示換行,會有一個tuple用來存貯這個文件中用到過的換行符。b: 表示對二進制文件進行操作(圖片、視頻)。 t: 對文本文件進行操作。 1.open使用open打開文件后一定要記得調用文件對象的close()方法。比如可以用try/finally語句來確保最后能關閉文件。file_object = open('thefile.txt')try:all_the_text = file_object.read( )finally:file_object.close( )注:不能把open語句放在try塊里,因為當打開文件出現異常時,文件對象file_object無法執行close()方法。2.讀文件讀文本文件input = open('data', 'r')#第二個參數默認為rinput = open('data')讀二進制文件input = open('data', 'rb')讀取所有內容file_object = open('thefile.txt')try:all_the_text = file_object.read( )finally:file_object.close( )讀固定字節file_object = open('abinfile', 'rb')try:while True:chunk = file_object.read(100)if not chunk:breakdo_something_with(chunk)finally:file_object.close( )讀每行list_of_all_the_lines = file_object.readlines( )如果文件是文本文件,還可以直接遍歷文件對象獲取每行:for line in file_object:process line3.寫文件寫文本文件output = open('data', 'w')寫二進制文件output = open('data', 'wb')追加寫文件output = open('data', 'w+')寫數據file_object = open('thefile.txt', 'w')file_object.write(all_the_text)file_object.close( )寫入多行file_object.writelines(list_of_text_strings)注意,調用writelines寫入多行在性能上會比使用write一次性寫入要高。?
讀文件
以讀方式打開文件后可以調用這三個函數:read() \ readline() \ readlines()
他們都可以傳遞一個int來指定需要讀取的總Size(Bytes)。
注意:因為讀取的文件會緩存到內存中,所以當需要讀取的文件Size大于內存時,需要指定每次讀入的Size。
read()讀取文件內容
read(…) read([size]) -> read at most size bytes, returned as a string. If the size argument is negative or omitted, read until EOF is reached. Notice that when in non-blocking mode, less data than what was requested may be returned, even if no size parameter was given. 讀取指定Size的內容,缺省參數為全部內容,返回一個String類型對象。readline() 獲取文件一行的內容
readline(…) readline([size]) -> next line from the file, as a string. Retain newline. A non-negative size argument limits the maximum number of bytes to return (an incomplete line may be returned then). Return an empty string at EOF. 讀取文件中的一行含有行結束符的內容,每執行一次會自動獲取往下一行的內容,返回一個String。 當讀取到最后一行再執行此函數時,會返回一個空String,不會報錯。一個綜合例子:
open() + fileObject.readline() + try..finally + String.split() + os.path.exists()
因為readline()函數返回的是String類型對象,所以我們可以使用循環來遍歷這一行中所有的元素。
readlines() 讀取文件所有行的內容
readlines(…) readlines([size]) -> list of strings, each a line from the file. Call readline() repeatedly and return a list of the lines so read. The optional size argument, if given, is an approximate bound on the total number of bytes in the lines returned. 獲取文件所有的內容,并返回一個以每行內容作為一個String元素的List類型對象,本質是通過循環調用readline()實現的。 pwd = open('fileOperation.txt','r') content = pwd.readlines() print content print content[0] print content[0][0]修改指定行的內容:
cfg = open(cfgUrl,'r+') cfgFile = cfg.readlines() cfgFile[lineNum] = cfgStrcfg = open(cfgUrl,'w+') cfg.writelines(cfgFile) cfg.flush() #刷新內存的緩存區,即將緩存區中的內容寫入到磁盤,但不會關閉文件。 cfg.close()將文件以r+的方式打開,并返回一個對象。對對象的內容進行修改后,再將文件以w+的方式打開,將對象的內容寫入到文件中。實現對文件指定行的內容修改。
read()、readline()、readlines()的區別
read()和readlines()默認都是獲取文件的所有內容。但是read()返回一個String類型對象,元素是一個Char。readlines()返回一個List類型對象,元素是一個Sting。而readline()獲取文件的一行內容,返回是一個String。
?
寫文件
注意:調用write()、writeline()時,文件原有的內容會被清空,因為文件指針初始指向文件的首行首個字母,而進行寫操作實質就是在文件指針指向的位置開始寫入內容。
write()
write(…) write(str) -> None. Write string str to file. Note that due to buffering, flush() or close() may be needed before the file on disk reflects the data written. 將傳遞的String參數寫入并覆蓋文件內容,返回None。需要執行close()或flush()后才會將內存的數據寫入到文件中。 注意:當你在沒有調用close()函數之前,你是可以調用多次write()函數來實現追加額效果,即后來的write()函數的寫入的內容并不會覆蓋前一次使用write()函數寫入的內容,但是不會自動添加換行符。 pwd = open('fileOperation.txt','w') pwd.write('My name is JMilk') pwd.flush() pwd.write('My name is chocolate') pwd.flush() pwd.write('123') pwd.write('456') pwd.close()結果:My name is JMilkMy name is chocolate123456一個綜合例子:
open() + fileObject.write() + os.path.exists() + ergodicDictionary
import os def write_test(fileName,content_iterable):try:pwd = open(fileName,'w')for key,value in content_iterable.items():pwd.write(key+'\t'+value+'\n') #傳入String類型參數同時加入換行符finally:pwd.close()if __name__ == '__main__':fileName = '/usr/local/src/pyScript/fileOperation.txt'dic = {'name':'Jmilk','age':'23','city':'BJ'}if os.path.exists(fileName):write_test(fileName,dic)else:print 'File not exist!'結果: city BJ age 23 name Jmilkwritelines() 寫入多行內容
writelines(…) writelines(sequence_of_strings) -> None. Write the strings to the file. Note that newlines are not added. The sequence can be any iterable object producing strings. This is equivalent to calling write() for each string. 將傳遞的迭代對象的String元素逐個寫入文件,相當于每一行都調用write()函數,但是不會自動添加換行符。 import os def write_lines(fileName,content_iterable):try:pwd = open(fileName,'w')pwd.writelines(content_iterable) #傳遞List類型參數finally:pwd.close()if __name__ == '__main__':fileName = '/usr/local/src/pyScript/fileOperation.txt'li = ['my name is Jmilk'+'\n','My name is chocolate'+'\n'] #定義List時加入換行符if os.path.exists(fileName):write_lines(fileName,li)else:print 'File not exist!'結果: my name is Jmilk My name is chocolatewrite()和writelines()的區別
從上面兩個例子中可以看出,write()接受的是String類型參數,所以可以在()中對實參進行修改加入’\n’。而writelines()接受的是iterable類型參數,并且iteraber對象的元素需要為String類型,只能在定義iterable的時候加入’\n’。在寫入多行內容時writelines()會比write()更有效率。再一次反映?數據結構決定了對象操作這一句話,所以對數據結構的理解是非常重要的。python數據結構,請參考:http://blog.csdn.net/jmilk/article/details/48391283
?
將標準輸出重定向寫入到指定文件
系統標準輸入、輸出、Err本質是一個類文件對象。重定向即:?
sys.stdout = fileObject_write #!/usr/bin/env python #Filename:stdoTest.py #coding=utf8 import sysfristOut = sys.stdout #備份初始的輸出文件對象 print type(fristOut)logOut = open('/usr/local/src/pyScript/out.log','w') sys.stdout = logOut #重定向輸出到新的文件對象 print 'Test stdout.' #重定向后,不會打印到屏幕logOut.close() #關閉open()打開的文件對象 sys.stdout = fristOut #還原輸出文件對象?
文件指針
文件指針:當使用open()函數打開一個文件并返回一個文件對象后,在文件對象中會存放著當前”光標”在文件中的位置,對文件進行的讀、寫、截斷操作都是基于文件指針,并從文件指針+1開始進行的操作。。這個位置稱為文件指針(從文件頭部開始計算的字節數),與C語言額指針概念相似,實質是文件中位置的標識。大部分的文件操作都是基于文件指針來實現的。注意:當對文件進行了讀、寫操作后都會改變文件指針的值。
tell():查詢文件中光標位置
seek():光標定位
tell()獲取當前文件指針(位置)
tell(…) tell() -> current file position, an integer (may be a long integer). pwd = open('fileOperation.txt','rw+') pwd.tell()結果: 0 // 因為新打開的文件,文件指針指向文件開頭位置seek()轉移文件指針
seek(…) seek(offset[, whence]) -> None. Move to new file position. 可以接收偏移量和選項作為參數,返回None。 當whence==0時,將文件指針從文件頭部轉移到”偏移量”指定的字符處。 當whence==1時,將文件指針從文件的當前位置往后轉移”偏移量”指定的字符數。 當whence==2時,將文件指針從文件尾部向前移動”偏移量”指定的字符數。使用示例:
f = open('file','r') print(f.tell()) #光標默認在起始位置 f.seek(10) #把光標定位到第10個字符之后 print(f.tell()) #輸出10 f.close() ---------------------- f = open('file','w') print(f.tell()) #先清空內容,光標回到0位置 f.seek(10) print(f.tell()) f.close() ---------------------- f = open('file','a') print(f.tell()) #光標默認在最后位置 f.write('你好 世界') print(f.tell()) #光標向后9個字符,仍在最后位置 f.close()flush() 同步將數據從緩存轉移到磁盤
示例,實現進度條功能
import sys,time for i in range(40):sys.stdout.write('*')sys.stdout.flush() time.sleep(0.2)if __name__ == '__main__':pass# 下面代碼也能夠實現相同的功能 import time for i in range(40):print('*',end='',flush=True) #print中的flush參數time.sleep(0.2)truncate()截斷文件
不能在r模式下執行。w模式下,已經清空所有數據,使用truncate沒有任何意義。a模式下,截斷指定位置后的內容。
truncate(…) truncate([size]) -> None. Truncate the file to at most size bytes. Size defaults to the current file position, as returned by tell(). 默認從文件指針指向的位置開始截斷文件內容,也可以通過傳遞int參數n來指定截斷的起始位置,即改變文件指針的位置。 從文件指針指向的位置n開始,之后的文件內容(不包含n)全部刪除,以可修改mode打開的文件可以使用此方法。 f = open('file','a') f.truncate(6) #只顯示6個字節的內容(6個英文字符或三個漢字),后面的內容被清空。?
光標位置總結
一個漢字兩個字節,涉及光標位置的方法有4個:read、tell、seek、truncate。
#--------------------------光標總結head----------------------------------- f = open('file','r') print(f.read(6)) #6個字符 print(f.tell()) #位置12字節,一個漢字兩個字節 f.close()f = open('file','r') f.seek(6) #6個字節 print(f.tell()) f.close()f = open('file','a') print(f.tell()) #光標默認在最后位置 f.write('你好 世界') print(f.tell()) #光標向后9個字節,一個漢字兩個字節,仍在最后位置 182-->191 f.close()f = open('file','a',encoding='utf-8') print(f.truncate(6)) #由于需要光標定位位置,所以也是字節。只顯示6個字節的內容(6個英文字母或三個漢字,一個漢字兩個字節),后面的內容被清空。 f.close() #-----------------------------光標總結end---------------------------------?
一個綜合例子:?
truncate()+tell()+seek()
In [8]: %cat fileOperation.txt 0123456789In [9]: pwd = open('fileOperation.txt','rw+')In [10]: pwd.tell() Out[10]: 0In [11]: pwd.seek(5)In [12]: pwd.tell() Out[12]: 5In [13]: pwd.truncate()In [14]: pwd.close()In [15]: %cat fileOperation.txt 01234?
with語句
可以同時對多個文件同時操作,當with代碼塊執行完畢時,會自動關閉文件釋放內存資源,不用特意加f.close()?。
num = 0 with open('file','r') as f1,open('file2','w',encoding='utf8') as f2:for line in f1:num += 1if num == 5:line = ''.join([line.strip(),'羊小羚'])f2.write(line)?
遍歷文件
from __future__ import print_function import osroot_dir = "d:/" # 指明被遍歷的文件夾# 三個參數:分別返回1.父目錄 2.所有文件夾名字(不含路徑) 3.所有文件名字 for parent, dir_names, file_names in os.walk(root_dir):for dir_name in dir_names: # 輸出文件夾信息print "parent is:" + parentprint "dirname is" + dir_namefor file_name in file_names: # 輸出文件信息print "parent is:" + parentprint "filename is:" + file_nameprint "the full name of the file is:" + os.path.join(parent, file_name) # 輸出文件路徑信息基于字符read & write
最基本的文件操作當然就是在文件中讀寫數據。這也是很容易掌握的。現在打開一個文件以進行寫操作:1. fileHandle = open ( 'test.txt', 'w' )fileHandle = open ( 'test.txt', 'w' )‘w'是指文件將被寫入數據,語句的其它部分很好理解。下一步就是將數據寫入文件:1. fileHandle.write ( 'This is a test.\nReally, it is.' )fileHandle.write ( 'This is a test.\nReally, it is.' )這個語句將“This is a test.”寫入文件的第一行,“Really, it is.”寫入文件的第二行。最后,我們需要做清理工作,并且關閉文件:1. fileHandle.close()fileHandle.close()正如你所見,在Python的面向對象機制下,這確實非常簡單。需要注意的是,當你再次使用“w”方式在文件中寫數據,所有原來的內容都會被刪除。如果想保留原來的內容,可以使用“a”方式在文件中結尾附加數據:1. fileHandle = open ( 'test.txt', 'a' ) 2. fileHandle.write ( '\n\nBottom line.' ) 3. fileHandle.close()fileHandle = open ( 'test.txt', 'a' ) fileHandle.write ( '\n\nBottom line.' ) fileHandle.close()然后,我們讀取test.txt,并將內容顯示出來:1. fileHandle = open ( 'test.txt' ) 2. print fileHandle.read() 3. fileHandle.close()fileHandle = open ( 'test.txt' ) print fileHandle.read() fileHandle.close()以上語句將讀取整個文件并顯示其中的數據。基于行的讀寫 line
1. fileHandle = open ( 'test.txt' ) 2. print fileHandle.readline() # "This is a test." 3. fileHandle.close() fileHandle = open ( 'test.txt' ) print fileHandle.readline() # "This is a test." fileHandle.close() 同時,也可以將文件內容保存到一個list中: 1. fileHandle = open ( 'test.txt' ) 2. fileList = fileHandle.readlines() 3. for fileLine in fileList: 4. print '>>', fileLine 5. fileHandle.close() fileHandle = open ( 'test.txt' ) fileList = fileHandle.readlines() for fileLine in fileList: print '>>', fileLine fileHandle.close() 或者在文件中一次讀取幾個字節的內容:1. fileHandle = open ( 'test.txt' ) 2. print fileHandle.read ( 1 ) # "T" 3. fileHandle.seek ( 4 ) 4. print FileHandle.read ( 1 ) # " "(原文有錯)fileHandle = open ( 'test.txt' ) print fileHandle.read ( 1 ) # "T" fileHandle.seek ( 4 ) print FileHandle.read ( 1 ) # " "(原文有錯)隨機訪問文件中的位置 seek
Python在讀取一個文件時,會記住其在文件中的位置,如下所示:1. fileHandle = open ( 'test.txt' ) 2. garbage = fileHandle.readline() 3. fileHandle.readline() # "Really, it is."fileHandle.close()fileHandle = open ( 'test.txt' ) garbage = fileHandle.readline() fileHandle.readline() # "Really, it is."fileHandle.close()可以看到,只有第二行顯示出來。然而,我們可以讓Python從頭開始讀來解決這個問題:1. fileHandle = open ( 'test.txt' ) 2. garbage = fileHandle.readline() 3. fileHandle.seek ( 0 ) 4. print fileHandle.readline() # "This is a test." 5. fileHandle.close()fileHandle = open ( 'test.txt' ) garbage = fileHandle.readline() fileHandle.seek ( 0 ) print fileHandle.readline() # "This is a test." fileHandle.close()在上面這個例子中,我們讓Python從文件第一個字節開始讀取數據。所以,第一行文字顯示了出來。當然,我們也可以獲取Python在文件中的位置:1. fileHandle = open ( 'test.txt' ) 2. print fileHandle.readline() # "This is a test." 3. print fileHandle.tell() # "17" 4. print fileHandle.readline() # "Really, it is."fileHandle = open ( 'test.txt' ) print fileHandle.readline() # "This is a test." print fileHandle.tell() # "17" print fileHandle.readline() # "Really, it is."二進制方式讀寫
在Windows和Macintosh環境下,有時可能需要以二進制方式讀寫文件,比如圖片和可執行文件。此時,只要在打開文件的方式參數中增加一個“b”即可:1. fileHandle = open ( 'testBinary.txt', 'wb' ) 2. fileHandle.write ( 'There is no spoon.' ) 3. fileHandle.close()fileHandle = open ( 'testBinary.txt', 'wb' ) fileHandle.write ( 'There is no spoon.' ) fileHandle.close()1. fileHandle = open ( 'testBinary.txt', 'rb' ) 2. print fileHandle.read() 3. fileHandle.close()fileHandle = open ( 'testBinary.txt', 'rb' ) print fileHandle.read() fileHandle.close()python本身并沒有對二進制進行支持,不過提供了一個模塊來彌補,就是struct模塊。
# python沒有二進制類型,但可以存儲二進制類型的數據,就是用string字符串類型來存儲二進制數據, # 這也沒關系,因為string是以1個字節為單位的。import struct a=12.34#將a變為二進制 bytes=struct.pack('i',a) #此時bytes就是一個string字符串,字符串按字節同a的二進制存儲內容相同。#再進行反操作。現有二進制數據bytes,(其實就是字符串),將它反過來轉換成python的數據類型:a,=struct.unpack('i',bytes) #注意,unpack返回的是tuple# 所以如果只有一個變量的話: bytes=struct.pack('i',a)# 那么,解碼的時候需要這樣 a,=struct.unpack('i',bytes) 或者 (a,)=struct.unpack('i',bytes)#如果直接用a=struct.unpack('i',bytes),那么 a=(12.34,) ,是一個tuple而不是原來的浮點數了。 #如果是由多個數據構成的,可以這樣: a='hello' b='world!' c=2 d=45.123 bytes=struct.pack('5s6sif',a,b,c,d)# 此時的bytes就是二進制形式的數據了,可以直接寫入文件比如 binfile.write(bytes) # 然后,當我們需要時可以再讀出來,bytes=binfile.read() # 再通過struct.unpack()解碼成python變量 a,b,c,d=struct.unpack('5s6sif',bytes)'5s6sif'這個叫做fmt,就是格式化字符串,由數字加字符構成,5s表示占5個字符的字符串,2i,表示2個整數等等, 下面是可用的字符及類型,ctype表示可以與python中的類型一一對應。存儲對象(序列化存儲)
使用上面的模塊,可以實現在文件中對字符串的讀寫。 然而,有的時候,你可能需要傳遞其它類型的數據,如list、tuple、dictionary和其它對象。在Python中,你可以使用Pickling來完成。你可以使用Python標準庫中的“pickle”模塊完成數據轉儲。
下面,我們來編組一個包含字符串和數字的list:
存儲更加復雜的數據:
import picklefileHandle = open('pickleFile.txt', 'w') testList = [123, {'Calories': 190}, 'Mr. Anderson', [1, 2, 7]] pickle.dump(testList, fileHandle) fileHandle.close()fileHandle = open('pickleFile.txt') testList = pickle.load(fileHandle) fileHandle.close()使用Python的“pickle”模塊編組確實很簡單。眾多對象可以通過它來存儲到文件中。如果可以的話,“cPickle”同樣勝任這個工作。它和“pickle”模塊一樣,但是速度更快:
import cPicklefileHandle = open('pickleFile.txt', 'w') cPickle.dump(1776, fileHandle) fileHandle.close()?
?
?
?
總結
以上是生活随笔為你收集整理的简明 Python 教程学习笔记_7_文件操作(os、shutil、pathlib )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CompletableFuture详解~
- 下一篇: python3 爬虫实战:mitmpro