1 文件路徑名操作
對於文件路徑名的操作在編程中是必不可少的,比如說,有時候要列舉一個路徑下的文件,那么首先就要獲取一個路徑,再就是路徑名的一個拼接問題,通過字符串的拼接就可以得到一個路徑名。Python中3.4版本前使用os.path模塊中的函數來操作路徑名;3.4版本開始提供pathlib模塊,使用Path對象來對目錄和文件進行操作。
2 os.path模塊
1 from os import path 2 3 p = path.join('/etc', 'sysconfig', 'network') # 根據不同的系統,將每個字符串組合成路徑形式 4 print(type(p), p) 5 print(path.exists(p)) # 判斷路徑在當前系統中是否存在 6 print(path.split(p)) # (head, tail)將路徑中的最后一個目錄或者文件與前面的路徑分開 7 print(path.abspath('.')) # 返回當前工作路徑,'.'代表當前路徑 8 p = path.join('o:/', p, 'test.txt') 9 print(path.dirname(p)) # 取目錄名 10 print(path.basename(p)) # 取基名 11 print(path.splitdrive(p)) # 將盤符名和文件路徑名分開(對於windows有盤符之分,在Linux中沒有盤符) 12 13 p1 = path.abspath(__file__) # 取當前文件所在的路徑 14 print(p1, path.basename(p1)) 15 while p1 != path.dirname(p1): # 每次取上級目錄中的基名 16 p1 = path.dirname(p1) 17 print(p1, path.basename(p1))
3 pathlib模塊
3.1 目錄操作
3.1.1 路徑拼接和分解
- 操作符"/"對路徑拼接
“/”操作符可以對兩個Path對象進行拼接、字符串和Path對象或者Path對象和字符串進行拼接
- parts屬性
parts屬性,可以返回路徑中的每一個部分
- joinpath
joinpath(*other)連接多個字符串到Path對象中
1 from pathlib import Path 2 3 p = Path() # 返回當前目錄 4 p = Path('a', 'b', 'c/d') # 當前目錄下的a/b/c/d 5 p = Path('/etc') # 返回根下的etc目錄 6 7 p = Path() 8 p = p / 'a' 9 p1 = 'b' / p 10 p2 = Path('c') 11 p3 = p2 / p1 12 print(p3.parts) 13 p3.joinpath('etc', 'init.d', Path('httpd'))
3.1.2 獲取路徑
- str獲取路徑字符串
- bytes獲取路徑字符串的bytes
1 p = Path('/etc') 2 print(str(p), bytes(p))
3.1.3 獲取路徑中的父目錄
- parent屬性返回目錄的邏輯父目錄
- parents屬性返回父目錄序列,索引0是直接的父目錄
1 p = Path('/a/b/c/d') 2 print(p.parent.parent) # 返回當前路徑的父目錄的父目錄即/a/b 3 for x in p.parents: # 將當前路徑的每一級的父目錄序列化 4 print(x)
3.1.4 其他屬性及方法
| 屬性 | 含義 |
| name | 目錄的最后一個部分 |
| stem | 目錄最后一個部分,不包含后綴 |
| suffix | 目錄中最后一個部分的擴展名 |
| suffixes | 返回多個擴展名列表 |
和以上四個屬性相關的方法:
- with_suffix(suffix)補充擴展名到路徑尾部,返回新的路徑,擴展名存在則修改之
- with_name(name)替換目錄最后一個部分並返回一個新的路徑
1 p = Path('/viktor/mysqlinstall/mysql.tar.gz') 2 print(p.name) # mysql.tar.gz 3 print(p.suffix) # .gz 4 print(p.suffixes) # ['.tar', '.gz'] 5 print(p.stem) # mysql.tar 6 print(p.with_name('mysql-5.tgz')) # /viktor/mysqlinstall/mysql-5.tgz 7 p = Path('README') 8 print(p.with_suffix('.txt')) # README.txt
和文件類型相關的方法:
| 方法 | 功能 |
| is_dir() | 是否是目錄,目錄存在返回True |
| is_file() | 是否是普通文件,文件存在返回True |
| is_symlink() | 是否軟鏈接 |
| is_socket() | 是否是socket文件 |
| is_block_device() | 是否是塊設備 |
| is_char_device() | 是否是字符設備 |
| is_absolute() | 是否是絕對路徑 |
其他幾種方法:
| 方法 | 功能 |
| cwd() | 返回當前工作目錄 |
| home() | 返回當前家目錄 |
| resolve() | 返回一個新的路徑,這個新路徑就是當前Path對象的絕對路徑。 如果是軟鏈接則直接被解析 |
| absolute() | 也可以獲取絕對路徑,但是推薦使用resolve() |
| exists() | 判斷目錄或文件是否存在 |
| rmdir() | 刪除空目錄。沒有提供判斷目錄為空的方法 |
| touch(mode=0o666, exist_ok=True) |
創建一個文件 |
| as_url() | 將路徑返回成URL,例如'file:///etc/passwd' |
| mkdir(mode=0o777, parents=False, exists_ok=False) |
parents參數是判斷是否創建父目錄,True等同於mkdir -p; False時,父目錄不存在,則拋出FileNotFoundError exist_ok參數,在3.5版本加入。False時,路徑存在, 拋出FileExistsError;True時,FileExistsError被忽略 |
| iterdir() | 迭代當前目錄 |
1 p = Path() 2 p /= 'a/b/c/d' 3 p.exists() # True 4 5 # 創建目錄 6 p.mkdir() # 如果p對象的路徑存在拋出FileExistsError,否則拋出FileNotFoundError 7 p.mkdir(parents=True) 8 p.exists() # True 9 p.mkdir(parents=Ture) # 拋出FileExistsError 10 p.mkdir(parents=True, exist_ok=True) # 忽略FileExistsError 11 p /= 'readme.txt' 12 p.parent.rmdir() # 刪除readme.txt的父目錄,此時真實目錄中已經不存在d目錄 13 p.parent.exists() # False 'a/b/c' 14 p.mkdir() # FileNotFoundError 15 p.mkdir(parent=True) # 成功
實現遍歷,並判斷文件類型,如果是目錄是否可以判斷其是否為空的代碼:
1 for x in p.parents[len(p.parents)-1].iterdir(): 2 print(x, end='\t') 3 if x.is_dir(): 4 flag = False 5 for _ in x.iterdir(): 6 flag = True 7 break 8 print('dir','Not Empty' if flag else 'Empty', sep='\t') 9 elif x.is_file(): 10 print('file') 11 else: 12 print('other file')
3.2 文件操作
pathlib中的Path還提供open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)方法打開文件,其使用方法類似內建函數open,返回一個文件對象。Ptyhon3.5后pathlib模塊新增加了一些方法,如下所示:
| 方法 | 功能 |
| read_bytes() | 以‘rb’讀取路徑對應文件,並返回二進制流 |
| read_text(encoding=None, errors=None) |
以'rt'方式讀取路徑對應文件,返回文本 |
| Path.write_bytes(data) | 以'wb'方式寫入數據到路徑對應文件 |
| write_text(data, encoding=None, errors=None) |
以'wt'方式寫入字符串到路徑對應文件 |
1 p = Path("my_binary_file") 2 p.write_bytes(b'Binary file contents') # 以'wb'形式向p路徑對象寫入數據 3 p.read_bytes() 4 5 p = Path("my_text_file") 6 p.write_text('Text file contents') # 以'wt'形式向p路徑對象寫入數據 7 p.read_text() 8 9 with p.open() as f: 10 print(f.read(5))
