文章目錄
文件操作之讀文件
說明
open() 方法
Python open() 方法用於打開一個文件,並返回文件對象,在對文件進行處理過程都需要使用到這個函數,如果該文件無法被打開,會拋出 OSError。
注意:使用 open() 方法一定要保證關閉文件對象,即調用 close() 方法。
open() 函數常用形式是接收兩個參數:文件名(file)和模式(mode):open(file, mode='r')
完整的語法格式爲:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
參數說明:
file: 必需,文件路徑(相對或者絕對路徑)。
mode: 可選,文件打開模式
buffering: 設置緩衝
encoding: 一般使用utf8
errors: 報錯級別
newline: 區分換行符
closefd: 傳入的file參數類型
opener:
mode 參數有:
模式 | 描述 |
---|---|
t | 文本模式 (默認)。 |
x | 寫模式,新建一個文件,如果該文件已存在則會報錯。 |
b | 二進制模式。 可以用來讀取或拷貝圖片呢,下面有demo實驗 |
+ | 打開一個文件進行更新(可讀可寫)。 |
U | 通用換行模式(不推薦)。 |
r | 以只讀方式打開文件。文件的指針將會放在文件的開頭。這是默認模式。 |
rb | 以二進制格式打開一個文件用於只讀。文件指針將會放在文件的開頭。這是默認模式。一般用於非文本文件如圖片等。 |
r+ | 打開一個文件用於讀寫。文件指針將會放在文件的開頭。 |
rb+ | 以二進制格式打開一個文件用於讀寫。文件指針將會放在文件的開頭。一般用於非文本文件如圖片等。 |
w | 打開一個文件只用於寫入。如果該文件已存在則打開文件,並從開頭開始編輯,即原有內容會被刪除。如果該文件不存在,創建新文件。 |
wb | 以二進制格式打開一個文件只用於寫入。如果該文件已存在則打開文件,並從開頭開始編輯,即原有內容會被刪除。如果該文件不存在,創建新文件。一般用於非文本文件如圖片等。 |
w+ | 打開一個文件用於讀寫。如果該文件已存在則打開文件,並從開頭開始編輯,即原有內容會被刪除。如果該文件不存在,創建新文 |
wb+ | 以二進制格式打開一個文件用於讀寫。如果該文件已存在則打開文件,並從開頭開始編輯,即原有內容會被刪除。如果該文件不存在,創建新文件。一般用於非文本文件如圖片等。 |
a | 打開一個文件用於追加。如果該文件已存在,文件指針將會放在文件的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該文件不存在,創建新文件進行寫入。 |
ab | 以二進制格式打開一個文件用於追加。如果該文件已存在,文件指針將會放在文件的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該文件不存在,創建新文件進行寫入。 |
a+ | 打開一個文件用於讀寫。如果該文件已存在,文件指針將會放在文件的結尾。文件打開時會是追加模式。如果該文件不存在,創建新文件用於讀寫。 |
ab+ | 以二進制格式打開一個文件用於追加。如果該文件已存在,文件指針將會放在文件的結尾。如果該文件不存在,創建新文件用於讀寫。 |
默認爲文本模式,如果要以二進制模式打開,加上 b 。
- file 對象
file 對象使用 open 函數來創建,下表列出了 file 對象常用的函數:
序號 | 方法及描述 |
---|---|
1 | file.close() 關閉文件。關閉後文件不能再進行讀寫操作。 |
2 | file.flush()刷新文件內部緩衝,直接把內部緩衝區的數據立刻寫入文件, 而不是被動的等待輸出緩衝區寫入。 |
3 | file.fileno()返回一個整型的文件描述符(file descriptor FD 整型), 可以用在如os模塊的read方法等一些底層操作上。 |
4 | file.isatty()如果文件連接到一個終端設備返回 True,否則返回 False。 |
5 | file.next()返回文件下一行。 |
6 | file.read([size])從文件讀取指定的字節數,如果未給定或爲負則讀取所有。seze=數字,數字代表字符串數量。 |
7 | file.readline([size])讀取整行,包括 “\n” 字符(自帶)。f.readline().strip()去掉\n符 ,size是一行中的多少字符 |
8 | file.readlines([sizeint])讀取所有行並返回列表,若給定sizeint>0,則是設置一次讀多少字節,這是爲了減輕讀取壓力。如果要去掉自帶\n,要用 for循環遍歷:for i in file.readlines() : print(i.strip()) |
9 | file.seek(offset[, whence])設置文件當前位置 |
10 | file.tell()返回文件當前位置。 |
11 | file.truncate([size])截取文件,截取的字節通過size指定,默認爲當前文件位置。 |
12 | file.write(str)將字符串寫入文件,返回的是寫入的字符長度。 |
13 | file.writelines(sequence)向文件寫入一個序列字符串列表,如果需要換行則要自己加入每行的換行符。 |
讀取文件 實操
當前包中讀取
先在當前包中建一個txt 文件把,然後自定義一些內容:
然後新建一個py文件:
# -- 讀取文件
f = open('file_tst.txt') # 打開一個文件,返回一個對象f
print(f.read()) # 一次性讀取所有內容
f.close() # 文件操作後一定要關閉
騷氣一點,可以放在try中:
# -- 讀取文件
try:
f = open('file_tst.txt') # 打開一個文件,返回一個對象f
except FileExistsError as e:
print('文件找不到: ',e)
else:
print(f.read()) # 一次性讀取所有內容
finally:
if f:
f.close() # 文件操作後一定要關閉
上面代碼可以使用with…as簡寫。 真實環境中,很多都是用的下面這種寫法,你現在可以不會寫,但你得看得懂!!!!!
#簡寫,使用with...as 語句,會自動調用close()
with open('file_tst.txt') as e:
print(f.read())
讀取文件加上參數說明:
如果文件中有中文,如果我們不指定字符集,可能會亂碼:
所以我們要指定字符集(如果不清楚,看上面的說明,裏面有每個參數的詳細解釋),如果報錯就加個單引號:open(file, encoding='utf8')
和幾個常用參數對象說明!!!!
# -- 讀取文件
try:
f = open('file_tst.txt',encoding='utf8') # 打開一個文件,返回一個對象f
except FileExistsError as e:
print('文件找不到: ',e)
else:
# print(f.read()) #讀取所有
print(f.read(20)) # 讀取20個字符串
print('*'*50)
print(f.readline()) #和read不能同時存在,否則不會輸出內容
print('*'*50)
# print(f.readlines()) #讀取所有內容,以列表方式展現,自帶\n
for i in f.readlines(): # 去掉自帶 \n,輸出結果好像和 read() 無異。,且不能和read()同時存在
print(i.strip())
finally:
if f:
f.close() # 文件操作後一定要關閉
文件操作之寫文件
單獨拿出來說 是怕你沒注意看!!!!
命令也是open,使用文件看讀文件中的說明!!!
寫文件也就是open的一個對象而已:
file.writelines(sequence)
向文件寫入一個序列字符串列表,如果需要換行則要自己加入每行的換行符。
來一個demo看效果:
# -- 讀取文件
try:
f = open('file_tst.txt',encoding='utf8') # 打開一個文件,返回一個對象f
except FileExistsError as e:
print('文件找不到: ',e)
else:
# print(f.read()) #讀取所有
print(f.read(20)) # 讀取20個字符串
print('*'*50)
print(f.readline()) #和read不能同時存在,否則不會輸出內容
print('*'*50)
# print(f.readlines()) #讀取所有內容,以列表方式展現,自帶\n
for i in f.readlines(): # 去掉自帶 \n,輸出結果好像和 read() 無異。,且不能和read()同時存在
print(i.strip())
finally:
if f:
f.close() # 文件操作後一定要關閉
#--寫文件
with open('file_tst.txt',mode='a',encoding='utf8') as g: # mode='a'是追加的意思,必須要
g.write('這是一個很帥的男人\n') #寫入該內容並回車
g.wr
去文件看內容:
注,因爲我執行了2次,所以追加了2次內容!!!
二進制拷貝圖片
# --讀寫二進制文件
# 以複製一張圖片爲例
# 前提條件你的先 放一張圖片在當前包中
with open('zhuomian.png',mode='rb') as write: #讀取圖片文件
with open('new_zhuomian.png',mode='wb') as out: #之前說了,這是放執行代碼塊,這裏執行拷貝代碼
out.write(write.read())
print('拷貝成功')
文件操作之os模塊
說明
os模塊可以幫助我們直接對操作系統進行操作,我們可以直接調用操作系統的命令和可執行文件,還能操作文件和目錄等等,是系統運維的核心基礎。
os模塊
import os
# 返回當前操作系統的類型
print(os.name) # windows->nt linux和unix->posix java虛擬機->java
# 當前系統路徑分隔符
print(os.sep) # windows->\ linux和unix->/
# getcwd() 獲取當前工作目錄
print(os.getcwd()) # D:\Project\pythonTest
# listdir() 獲取指定目錄下所有文件和文件夾相對路徑,保存到列表中
ls = os.listdir('./') # ./表示當前文件所在目錄
print(ls) # ['.idea', '.vscode', 'test.py', 'test_file']
# mkdir() 用於創建文件夾
os.mkdir('test_file2') # 如果不指定絕對路徑,則默認在當前文件夾下創建
# mkdir創建的文件夾名不能與已存在的重命名,否則報錯
os.mkdir('test_file2') # FileExistsError: [WinError 183] 當文件已存在時,無法創建該文件。: 'test_file2'
# rename() 對文件或者文件夾重命名
os.rename('電影', 'movies')
# remove() 刪除文件
os.remove('a.txt') # 如果文件不存在,則報錯FileNotFoundError: [WinError 2] 系統找不到指定的文件。: 'a.txt'
#一般建議 加個 if判斷條件,否則會報錯
if os.path.exists('new_zhuomian.png'): #os.path模快自帶判斷條件
os.remove('new_zhuomian.png') # 如果不加這個,如果不存在就會報錯
else:# 這個條件不要也可
print('文件不存在')
# rmdir() 用於刪除文件夾
os.rmdir('test_file2') # 只能刪除空的文件夾, 否則報錯:OSError: [WinError 145] 目錄不是空的。: 'test_file2'
#一般建議 加個 if判斷條件,否則會報錯
if os.path.exists('new_zhuomian'): #os.path模快自帶判斷條件
os.remove('new_zhuomian') # 如果不加這個,如果不存在就會報錯
else:# 這個條件不要也可
print('文件夾不存在')
os.rmdir('test_fil') # FileNotFoundError: [WinError 2] 系統找不到指定的文件。: 'test_fil'
# 創建多級目錄
# os.makedirs('電影/小電影/金瓶梅') # 在當前目錄下創建多級目錄
# 刪除多級目錄
os.removedirs('電影/小電影/金瓶梅') # 同樣的只能刪除爲空的目錄
# chdir() 切換目錄
os.chdir('c:')
print(os.getcwd()) # C:\
# ../表示返回當前文件的上一級
os.makedirs(r'../技術/python/入門') # 當前py文件路徑爲: D:\Project\pythonTest\test.py, ../表示當前文件的上一級目錄,即Project下創建多級目錄
os.path模塊
os.path
模塊提供了目錄相關(路徑判斷、路徑切分、路徑鏈接、文件夾遍歷)的操作。
import os
print(os.path) # 輸出的是python環境的路徑 ==》 <module 'ntpath' from 'D:\\Python\\Python37\\lib\\ntpath.py'>
# os.path.isabs判斷是否爲絕對和相對路徑,如果傳的path是絕對路徑(以斜槓開頭),返回True;相對路徑爲False
print(os.path.isabs('D:/Project/pythonTest/test.py')) # True
print(os.path.isabs('/Project/pythonTest')) # True ,/根目錄,即所在的D盤
print(os.path.isabs('Project/pythonTest')) # False
# os.path.isdir 判斷是否是文件夾
print(os.path.isdir('movies')) # True
# os.path.isfile 判斷是否是文件
print(os.path.isfile('test.py')) # True
# os.path.exists判斷文件或目錄是否存在
print(os.path.exists('test.py')) # True
print(os.path.exists('movies1')) # False
path = r'D:\Project\pythonTest\test.py'
# os.path.getsize 獲得文件的大小(字節)
print(os.path.getsize(path)) # 1563
# os.path.abspath 返回絕對路徑
print(os.path.abspath('test.py')) # D:\Project\pythonTest\test.py
print(os.path.abspath('movies')) # D:\Project\pythonTest\movies
print(os.path.abspath('1')) # 1文件夾是不存在的,但是這裏相對當前目錄下的絕對路徑:D:\Project\pythonTest\1
# __file__獲取當前文件絕對路徑
print(__file__) # D:/Project/pythonTest/test.py
print(os.path.abspath(__file__)) # D:\Project\pythonTest\test.py
# os.path.dirname() 獲取當前工作目錄
print(os.path.dirname('/test_project/content/new')) # 獲取指定文件或文件夾所在的目錄的絕對路徑, /test_project/content
print(os.path.dirname(__file__)) # D:/Project/pythonTest
# os.path.join 拼接路徑
print(os.path.join('D:', r'\test')) # D:\test
# 如果各組件名首字母不包含’/’,則函數會自動加上
print(os.path.join('aa', 'bb', 'cc')) # aa\bb\cc
# 會從第一個以/開頭的參數開始拼接,之前的參數全部丟棄
print(os.path.join('/aa', 'bb', 'cc')) # /aa\bb\cc
print(os.path.join('aa', '/bb', 'cc')) # /bb\cc 以第一個/開頭開始拼接,所以bb之前的aa被丟棄了
# 當有多個/時,從最後一個開始
print(os.path.join('/aa', '/bb', '/cc')) # /cc
# 如果最後一個組件爲空,則生成的路徑以一個’/’分隔符結尾
print(os.path.join('aa', 'bb', '')) # /aa\bb\
path = r'D:\Project\pythonTest\test.py'
# os.path.split 返回文件的路徑和文件名, 以元組的形式
result = os.path.split(path) # 分割文件名
print(result) # ('D:\\Project\\pythonTest', 'test.py')
print(result[1]) # test.py 獲取文件名
# os.path.splitext 分割文件名和擴展名,以元組形式
print(os.path.splitext(path)) # ('D:\\Project\\pythonTest\\test', '.py')
os.walk方法
os.walk()用來遞歸遍歷所有文件和目錄,返回一個包含3個元素的元組
(dirpath, dirnames, filenames),生成器:
dirpath
:要列出指定目錄的路徑
dirnames
:目錄下的所有文件夾
filenames
:目錄下的所有文件
import os
path = os.getcwd()
print(path) # D:\Project\pythonTest
list_file = os.walk(path)
print(list_file) # <generator object walk at 0x0000021C76DE07C8>
all_files = []
for dirpath, dirnames, filenames in list_file:
print(dirpath)
for dir in dirnames:
all_files.append(os.path.join(dirpath, dir))
for file in filenames:
all_files.append(os.path.join(dirpath, file))
# 打印所有的子目錄和子文件
for file in all_files:
print(file)
shutil和zipfile模塊
shutil模塊是python標準庫中提供的,主要用來做文件和文件夾的拷貝,移動、刪除等;還可以做文件和文件夾的壓縮,解壓縮操作。os莫提供了對文件或目錄的一般操作,shutil模塊作爲補充,提供了移動、複製、壓縮、解壓等操作,這些os模塊都沒有提供。
import shutil
shutil.copyfile('test.py', 'test_copy.py') # 複製文件
shutil.copytree('movies', 'movies_copy') # 複製目錄
shutil.move( 'src(路徑)', 'dst(當前路徑則重命名,其他路徑則移動)') #移動文件、目錄。或者文件、目錄重命名。如果dst存在,則不可覆蓋
shutil.remove('file') #刪除文件
# 壓縮
shutil.make_archive('movies_copy', 'zip', 'movies') # 目標文件, zip 源文件
還有個模塊zipfile可以解壓縮:
import zipfile
# 壓縮
z1 = zipfile.ZipFile('test.zip', 'w')
z1.write('test.py')
z1.write('test_copy.py') # 將test.py和test_copy.py文件壓縮到test.zip中
z1.close()
# 解壓
z2 = zipfile.ZipFile('test.zip', 'r')
z2.extractall('test') # 解壓到test目錄下
z2.close()
遞歸實現遍歷所有文件和目錄
上面我們使用了os.walk方法實現了遍歷指定目錄下所有文件和目錄,現在我們通過遞歸自己實現這種遍歷。
import os
src_path = os.getcwd() # 獲取當前目錄絕對路徑
all_files = []
def get_all_files(src_path):
src_child = os.listdir(src_path) # 獲取指定目錄下的文件和目錄
for child in src_child:
src_child = os.path.join(src_path, child)
if os.path.isdir(src_child): # 判斷是否是目錄
get_all_files(src_child) # 如果是目錄,則回調
all_files.append(src_child)
get_all_files(src_path)
for f in all_files:
print(f)
上面使用方法都挺簡單的,之間按需要執行就可以了,下面會說到調用windows的操作,我會放圖片。
os調用操作系統命令
比如在windows系統下,我們在運行裏面輸入notepad.exe可打開記事本工具;
同樣,我們可以使用os模塊調用操作系統命令打開:
import os
os.system('notepad.exe') # 打開記事本
同樣我們還可以調用其他命令:
os.system('regedit') # 打開註冊表
os.system('ping www.hao123.com') # ping命令
os.system('cmd') # 打開dos窗口
os執行可執行文件
比如我們平常登錄微信,需要用鼠標雙擊打開登錄界面,使用os模塊也打開:
import os
#查看軟件路徑方法,右鍵-屬性-目標
#os.startfile(r"路徑") # 打開指定文件
# 如打開微信
os.startfile(r"C:\Program Files (x86)\Tencent\WeChat\WeChat.exe")