豬行天下之Python基礎——7.1 檔案儲存

coder-pig發表於2019-04-08

內容簡述:

  • 1、open()函式與檔案開啟模式
  • 2、file物件提供的函式
  • 3、常見的檔案操作示例
  • 4、os模組裡的常用函式
  • 5、實用程式碼示例

1、open()函式與檔案開啟模式

Python中讀寫檔案非常簡單,通過 open()函式 可以開啟檔案並返回檔案物件。我們可以使用help函式來檢視open函式具體的引數:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
複製程式碼

一般瞭解前兩個引數就夠了,file引數代表檔名,如果不帶上路徑的話,會在當前資料夾裡查詢, 而mode引數代表檔案的開啟模式,有如下表所示的幾種開啟模式:

模式 作用
r 只讀模式開啟,預設
w 寫模式開啟,若檔案存在,先刪除,然後重新建立
a 追加模式開啟,追加到檔案末尾,seek()指向其他地方也沒用,檔案不存在,自動建立
b 二進位制模式開啟
t 文字模式開啟,預設
+ 可讀寫模式,可配合其他模式使用,比如r+,w+
x 如果檔案已存在,用此模式開啟會引發異常
U 通用換行符支援

另外,實用open函式開啟檔案時要做下:異常捕獲,比如下面這樣的程式碼:

f = open('test.txt''r')
複製程式碼

如果test.txt檔案不存在的話,會丟擲一個FileNotFoundError錯誤,所以需要進行異常捕獲。另外,檔案使用完畢後必須關閉,檔案物件會佔用作業系統的資源,作業系統同一時間能開啟的檔案數量也是有限的。所以為了保證正常或發生異常的時候檔案都能關閉,需要把關閉操作寫到finally塊裡,示例程式碼如下:

try:
    f = open('test.txt''r')
    print(f.read())
finally:
    if f:
        f.close()
複製程式碼

但是每次都要這樣寫的話顯得有些繁瑣了,可以使用Python提供的with語句來簡化這個操作。

with open('test/txt''r'as f:
    print(f.read())
複製程式碼

相比每次都要寫try-finally異常捕獲,這種方式簡潔得多,而且不用怕忘記關閉檔案。


2、file物件提供的函式

file物件提供瞭如下表所示的可供呼叫的方法:

函式 作用
close() 關閉檔案,關閉後檔案不能再進行讀寫操作
read(size=-1) 從檔案讀取指定的位元組數,如果未設定或為負數,讀取所有
next() 返回檔案下一行
readline() 讀取整行,包括換行符'\n'
seek(offset, from) 設定當前檔案指標的位置,從from(0檔案起始位置,1當前位置,
2檔案末尾)偏移offset個位元組
tell() 返回檔案的當前位置
write(str) 將字串寫入檔案
writelines(seq) 寫入一個序列字串列表,如果要換行,需要自己加入每行的換行符
truncate([size]) 截斷檔案並返回截斷的位元組長度,指定長度就從開頭開始截斷指定長度,
其餘內容刪除;不指定的話,從開頭擷取到當前位置,其餘內容刪除。

3、常見的檔案操作示例

檔案的常用操作有建立,寫入,讀取,還有追加,程式碼示例如下:

# 1.建立一個可讀寫的檔案
def mk_file(file):
    with open(file, 'w+', encoding='UTF-8'as f:
        print("建立了一個可讀寫的檔案:%s" % file)


# 2.往檔案中寫入內容
def write_to_file(file, content):
    with open(file, 'w+', encoding='UTF-8'as f:
        f.write(content + '\n')
        print("內容寫入成功!")


# 3.讀取檔案裡的內容
def read_from_file(file):
    with open(file, 'r+', encoding='UTF-8'as f:
        print("輸出檔案內容:" + f.read())


# 4.往檔案追加內容
def append_to_file(file, content):
    with open(file, 'a+', encoding='UTF-8'as f:
        f.write(content + '\n')
        print("內容追加成功!")


if __name__ == '__main__':
    file_name = 'test.txt'
    mk_file(file_name)
    write_to_file(file_name, "人生苦短我用Python!")
    read_from_file(file_name)
    append_to_file(file_name, "Hello Python!")
    read_from_file(file_name)
複製程式碼

執行結果如下

建立了一個可讀寫的檔案:test.txt
內容寫入成功!
輸出檔案內容:人生苦短我用Python

內容追加成功!
輸出檔案內容:人生苦短我用Python
Hello Python
複製程式碼

4、os模組裡的常用函式

Python中為我們提供了一個os模組用於處理檔案和目錄,除此之外它的子模組path模組還提供了檔案路徑相關的一些函式,通過這些函式可以完成檔案或者資料夾的批處理操作,比如檔案批量改名,內容替換等。


① os模組常用函式

os模組常用的函式如下表所示:

函式 作用
close() 關閉檔案,關閉後檔案不能再進行讀寫操作
getcwd() 返回當前工作目錄
chdir(path) 改變當前工作目錄
listdir(path='.') 不寫引數預設列舉當前目錄下所有檔案和資料夾,'.'當前目錄,
'..'上一層目錄
mkdir(path) 建立資料夾,若存在會丟擲FileExistsError異常
mkdirs(path) 可用於建立多層目錄
remove(path) 刪除指定檔案
rmdir(path) 刪除目錄
removedirs(path) 刪除多層目錄
rename(old,new) 重新命名檔案或資料夾
system(command) 呼叫系統提供的小工具,比如計算器
walk(top) 遍歷top引數指定路徑下所有子目錄,返回一個三元組(路徑,
[包含目錄],[包含檔案])
curdir 當前目錄(.)
pardir 上一節目錄(..)
sep 路徑分隔符,Win下是'\',Linux下是'/'
linesep 當前平臺使用的行終止符,win下是'\r\n',Linux下是'\n'
pathsep 輸出用於分割檔案路徑的字串
name 當前使用的作業系統
stat(path) 獲取檔案目錄資訊
environ 獲取系統環境變數
system("bash command") 執行shell命令,直接顯示

② os.path模組常用函式

os.path模組常用的函式如下表所示:

函式 作用
dirname(path) 獲得路徑名
basename(path) 獲得檔名
join(path1[,path2[,…]]) 將路徑名與檔名拼接成一個完整路徑
split(path) 分割路徑與檔名,返回元組(f_path, f_name),如果完全使用目錄,它也會將最後一個目錄作為檔名分離,且不會判斷檔案或目錄
是否存在
splitext(path) 分隔檔名與副檔名
getsize(file) 獲得檔案大小,單位是位元組
getatime(file) 獲得檔案最近訪問時間,返回的是浮點型秒數
getctime(file) 獲得檔案的建立時間,返回的是浮點型秒數
getmtime(file) 獲得檔案的修改時間,返回的是浮點型秒數
exists(path) 判斷路徑(檔案或目錄)是否存在
isabs(path) 判斷是否為決定路徑
isdir(path) 判斷是否存在且是一個目錄
isfile(path) 判斷是否存在且是一個檔案
islink(path) 判斷是否存在且是一個符號連結
ismount(path) 判斷是否存在且是一個掛載點
samefile(path1,path2) 判斷兩個路徑是否指向同一個檔案

5、實用程式碼示例

① 批量替換多個檔案中的內容

比如說現在有這樣一批檔案,檔案內容都是:

1.Java是一門物件導向程式語言,不僅吸收了C++語言的各種優點,還摒棄了C++
裡難以理解的多繼承、指標等概念,因此Java語言具有功能強大和簡單易用兩個特徵。
Java語言作為靜態物件導向程式語言的代表,極好地實現了物件導向理論,允許程式設計師
以優雅的思維方式進行復雜的程式設計。

現在需要把檔案裡的Java都替換成Python,我們可以通過編寫指令碼來完成這項繁瑣的工作,具體程式碼如下:

import os

def replace(dir_path, word_before, word_after):
    file_list = []
    # 遍歷獲得檔案地址
    for f in os.listdir(dir_path):
        file_list.append(os.path.join(dir_path, f))
    # 開啟檔案,按行讀取,替換對應內容
    for file in file_list:
        with open(file'r+'encoding='UTF-8'as f:
            content = f.read()
            f.seek(0)
            f.truncate()
            f.write(content.replace(word_before, word_after))

if __name__ == '__main__':
    replace(os.path.join(os.getcwd(), 'doc'), 'Java''Python')
複製程式碼

執行結果如下

1.Python是一門物件導向程式語言,不僅吸收了C++語言的各種優點,還摒棄了C++裡難以理解的多繼承、指標等概念,因此Python語言具有功能強大和簡單易用兩個特徵。Python語言作為靜態物件導向程式語言的代表,極好地實現了物件導向理論,允許程式設計師以優雅的思維方式進行復雜的程式設計。
複製程式碼

② 批量檔案重新命名

有時我們需要對一堆檔案進行批量命名,比如需要把下面這樣的圖片名字統一改成image_1這樣的形式。在學習本節之前,你可能需要複製下image_,然後一個個圖片重新命名,學習完本節後我們可以動手寫一個批量檔案重新命名的指令碼。

程式還是比較簡單的,分兩步:

  • 1.獲取某個資料夾裡所有的檔案完整路徑名
  • 2.呼叫file物件的rename函式僅限替換

具體程式碼如下

import os
def rename(file_dir, model_name, file_type):
    pos = 1
    # 獲取資料夾下所有檔案(包括資料夾)
    file_list = os.listdir(file_dir)
    for file in file_list:
        # 判斷是否為對應字尾的檔案
        if file.endswith(file_type):
            try:
                # 舊檔名
                old_name = os.path.join(file_dir, file)
                # 新檔名
                new_name = os.path.join(file_dir, model_name + str(pos) + file_type)
                os.rename(old_name, new_name)
                pos = pos + 1
            except:
                continue
rename(os.path.join(os.getcwd(), 'res'), 'image_''.png')
複製程式碼

執行結果如下

1s不到改完108個圖片,簡直不要太爽,真人生苦短,我用Python!


如果本文對你有所幫助,歡迎
留言,點贊,轉發
素質三連,謝謝?~


相關文章