Python中的os模塊是主要和系統操作相關的模塊,在平時的工作中會經常用到,花時間整理了os模塊的高頻使用方法,同時整理出使用時需要注意的點。歸納來講,os模塊的方法可以分爲:目錄操作、文件操作、路徑操作、系統操作等四大類,我們接下來依次進行介紹。
目錄操作相關
創建、刪除、重命名目錄
# 當前目錄下創建目錄,注意第二個參數mode,在Windows被忽略
os.mkdir("test_folder")
# 刪除目錄,如果目錄不爲空,則拋出OSError:[Errno 66] Directory not empty
os.rmdir("test_folder")
# 遍歷創建目錄,可以創建多個目錄,其中exist_ok爲False,表示目錄存在拋出異常。
os.makedirs("a/b/c", exist_ok=False)
# 遍歷刪除目錄,可以直接,注意如果目錄不爲空,會拋出OSError:[Errno 66] Directory not empty
os.removedirs("a/b/c")
# 對文件或者目錄進行重命名,不能對路徑做變更
os.rename("a", "b")
# os.rename的升級版本,可以重命名文件,也可以重命名文件的上級目錄。
os.renames("b", "a/b")
遍歷目錄
# 對目錄a下的文件進行遍歷,返回目錄下的名字列表,注意不會遍歷子目錄
file_name_list = os.listdir("a")
print(file_name_list)
'''
功能:會遞歸遍歷對目錄a下的文件和目錄
參數:topdown表示遍歷目錄的優先級(True先遍歷根目錄,False先遍歷子目錄)
onerror 當walk遇到錯誤時會調用
返回值:
parent 指的是父目錄,
dir_name返回parent目錄下所有的目錄
file_name返回parent目錄下所有的文件
'''
list_result = os.walk("a", topdown=True, onerror=None, followlinks=False)
for parent, dir_name, file_name in list_result:
print(parent)
print(dir_name)
print(file_name)
print("============")
# 和listdir類似,都是對第一層目錄遍歷,區別在於scandir返回的是迭代器
with os.scandir("a") as it:
print("*"*12)
for entry in it:
print(entry.name)
需要注意的是,如果要遍歷的目錄下文件數量比較多,比如數百萬個文件,那麼就可以使用os.scandir(),因爲如果這時使用listdir()會造成內存緊張。
獲取目錄
# 獲取當前工作目錄所在的絕對路徑
print(os.getcwd())
# 返回.. 表示當前目錄的上級目錄
print(os.pardir)
# 返回上級目錄,這裏用到了os.path.abspath,獲取絕對路徑
print(os.path.abspath(os.path.dirname(os.getcwd())))
# 用於改變當前工作目錄
os.chdir("a")
print(os.getcwd())
判斷目錄
# 判斷路徑a是否存在
print(os.path.exists("a"))
# 判斷路徑a是否是目錄
print(os.path.isdir("a"))
# 判斷路徑a是否是文件
print(os.path.isfile("a"))
文件屬性
'''
功能:返回文件/目錄對應的屬性
返回值:st_mode(權限模式)=16877, st_ino(inode節點號)=12897368202,
st_dev(inode所在設備號)=16777220, st_nlink(inode鏈接數)=5, st_uid(文件所有者id)=501,
st_gid(文件所有者的組id)=20, st_size(文件大小)=160, st_atime(上次訪問的時間)=1577449111,
st_mtime(最後一次修改的事件)=1577449111, st_ctime(創建時間)=1577449111)
'''
print(os.stat("."))
# 同樣,os也提供了單獨獲取某個屬性的方法
print(os.path.getatime("."))
print(os.path.getctime("."))
print(os.path.getmtime("."))
print(os.path.getsize("."))
# 修改文件的訪問時間和修改時間
os.utime(".", (1577449111, 1577449111))
在上面註釋中提到的inode,主要用來存儲文件的"元信息",比如文件的創建時間、文件的大小等,中文名叫作"索引節點"。
讀寫文件
# Python的os提供了open和write方法來讀寫文件
# 打開文件
fd = os.open("test3.txt", os.O_RDWR | os.O_CREAT)
# 這裏返回的是一個文件描述符
print(fd)
# 寫入字符串
os.write(fd, b"This is test")
# 將字符串刷新到硬盤上
os.sync()
# 關閉文件
os.close(fd)
# 作爲對比,Python提供了open方法可以更方便的操作文件,所以我們一般直接使用open方法。
with open("a/test3.txt", "wb") as f:
# 這裏返回的是一個操作文件的BufferedWriter對象
print(f)
f.write(b"aaaaaaaaa")
路徑操作
# 獲取路徑的相對路徑
print(os.path.abspath("."))
# 判斷路徑是否是相對路徑
print(os.path.isabs("."))
# 將路徑拼接在一起
print(os.path.join(os.getcwd(), "a","b"))
# 將傳入的路徑的最後一級目錄/文件拆分開,比如:傳入a/b/c/d 返回: a/b/c , d
print(os.path.split(os.getcwd()))
# 返回傳入路徑所在的目錄,比如:傳入a/b/c/d 返回:/a/b/c
print(os.path.dirname(os.getcwd()))
# 將傳入path分割爲路徑和擴展,比如:傳入a/b/c/d.txt 返回('a.b/c/d', '.text')
print(os.path.splitext(os.path.abspath("./a/test3.txt")))
執行系統命令
# 注意這裏執行的命令一定是在執行的操作系統存在的命令,比如在linux系統用ls,在windows系統用dir
# 在當前進程中打開一個子shell(子進程)來執行命令
# 返回值:命令的執行狀態 0 執行成功、非0,表示執行不成功。 會將命令的執行結果寫入到stdout中,也就是控制檯。
print(os.system("la"))
print("================")
'''
參數:cmd:要執行的命令。
mode:打開文件的模式,默認爲'r',用法與open()相同。
buffering:0意味着無緩衝;1意味着行緩衝;其它正值表示使用參數大小的緩衝。
負的bufsize意味着使用系統的默認值,一般來說,對於tty設備,它是行緩衝;對於其它文件,它是全緩衝。
返回:這個方法會返回一個管道,返回一個連接管道的文件對象,比如爲f,可以通過f.readlines()和f.read()來讀取返回值。
'''
with os.popen("ls", "r", 1) as p:
print(type(p))
r = p.read()
print(r)
print("end")
不過Python提供了更強大的subprocess模塊,使用subprocess.popen()方法會更加靈活。我們後面會專門寫文章來介紹subprocess這個模塊的各種方法的使用。
系統操作
# 返回當前進程的id
print(os.getpid())
# 返回操作系統的信息
print(os.uname())
# 返回系統的環境變量
print(os.environ)
# 返回系統的環境變量,PATH對應的值
print(os.environ.get('PATH'))
總結
上面總結了python3中os模塊常用的方法,主要圍繞對路徑、目錄及系統命令的操作,大家在平時使用過程中可以靈活使用上面的各種方法,有時候需要多個方法搭配使用。我給大家留兩個練習題,這是我之前寫python腳本碰到的問題:
- 獲取某個目錄下面最新的文件
- 將所有以error.log結尾的文件,全部放到某個對應目錄下。
大家可以思考下,然後在評論區寫下你的答案。
關注【公衆號:軟件測試佈道師】,回覆【python】,即可獲取【python自動化及編程實踐資料】