目的:文件名和路徑解析埋泵,組合车份,測試等拂苹。
使用os.path模塊中包含的函數(shù)編寫代碼以便在多個(gè)平臺上處理文件非常簡單厨剪。即使不打算在平臺之間移植的程序也應(yīng)該使用os.path來進(jìn)行可靠的文件名解析。
解析路徑
路徑解析依賴于在os中定義的幾個(gè)變量:
os.sep - 路徑各部分之間的分隔符(例如“/”或“\”)难裆。
os.extsep - 文件名和文件擴(kuò)展名之間的分隔符子檀。
os.pardir - 上級目錄(e.g., “..”)。
os.curdir - 當(dāng)前目錄 (e.g., “.”)乃戈。
split()函數(shù)將路徑分成兩個(gè)獨(dú)立的部分褂痰,并返回包含結(jié)果的元組。元組的第二個(gè)元素是路徑的最后一個(gè)元素症虑,第一個(gè)元素是之前的所有元素脐恩。
# ospath_split.py
import os.path
PATHS = [
'/one/two/three',
'/one/two/three/',
'/',
'.',
'',
]
for path in PATHS:
print('{!r:>17} : {}'.format(path, os.path.split(path)))
執(zhí)行結(jié)果
$ python3 ospath_split.py
'/one/two/three' : ('/one/two', 'three')
'/one/two/three/' : ('/one/two/three', '')
'/' : ('/', '')
'.' : ('', '.')
'' : ('', '')
basename()函數(shù)返回等價(jià)于split()第二部分的值。
import os.path
PATHS = [
'/one/two/three',
'/one/two/three/',
'/',
'.',
'',
]
for path in PATHS:
print('{!r:>17} : {!r}'.format(path, os.path.basename(path)))
執(zhí)行結(jié)果
$ python3 ospath_basename.py
'/one/two/three' : 'three'
'/one/two/three/' : ''
'/' : ''
'.' : '.'
'' : ''
完整路徑被分解到最后一個(gè)元素侦讨,無論是指文件還是目錄。如果路徑在目錄分隔符(os.sep)中結(jié)束苟翻,則basename是空的韵卤。
dirname() 函數(shù)返回分割路徑的第一部分:
import os.path
PATHS = [
'/one/two/three',
'/one/two/three/',
'/',
'.',
'',
]
for path in PATHS:
print('{!r:>17} : {!r}'.format(path, os.path.dirname(path)))
執(zhí)行結(jié)果
$ python3 ospath_dirname.py
'/one/two/three' : '/one/two'
'/one/two/three/' : '/one/two/three'
'/' : '/'
'.' : ''
'' : ''
將basename()的結(jié)果與dirname()結(jié)合起來得到原始路徑。
splitext()工作方式類似于split()崇猫,但將擴(kuò)展分隔符(而不是目錄分隔符)的路徑分開沈条。
import os.path
PATHS = [
'filename.txt',
'filename',
'/path/to/filename.txt',
'/',
'',
'my-archive.tar.gz',
'no-extension.',
]
for path in PATHS:
print('{!r:>21} : {!r}'.format(path, os.path.splitext(path)))
執(zhí)行結(jié)果
$ python3 ospath_splitext.py
'filename.txt' : ('filename', '.txt')
'filename' : ('filename', '')
'/path/to/filename.txt' : ('/path/to/filename', '.txt')
'/' : ('/', '')
'' : ('', '')
'my-archive.tar.gz' : ('my-archive.tar', '.gz')
'no-extension.' : ('no-extension', '.')
在查找擴(kuò)展名時(shí),只使用最后一次出現(xiàn)的os.extsep诅炉,所以如果文件名有多個(gè)擴(kuò)展名蜡歹,則將其分割結(jié)果保留在前綴的一部分。
commonprefix() 將路徑列表作為參數(shù)涕烧,并返回表示所有路徑中存在的公共前綴的單個(gè)字符串月而。該值可能表示實(shí)際上不存在的路徑,并且路徑分隔符不包含在考慮因素中议纯,所以前綴可能不會停止在分隔符邊界上父款。
import os.path
paths = ['/one/two/three/four',
'/one/two/threefold',
'/one/two/three/',
]
for path in paths:
print('PATH:', path)
print()
print('PREFIX:', os.path.commonprefix(paths))
執(zhí)行結(jié)果
$ python3 ospath_commonprefix.py
PATH: /one/two/three/four
PATH: /one/two/threefold
PATH: /one/two/three/
PREFIX: /one/two/three
commonpath()則會考慮os.seq。
import os.path
paths = ['/one/two/three/four',
'/one/two/threefold',
'/one/two/three/',
]
for path in paths:
print('PATH:', path)
print()
print('PREFIX:', os.path.commonpath(paths))
執(zhí)行結(jié)果
$ python3 ospath_commonpath.py
PATH: /one/two/three/four
PATH: /one/two/threefold
PATH: /one/two/three/
PREFIX: /one/two
參考資料
- 討論qq群144081101 591302926 567351477 釘釘免費(fèi)群21745728
- 本文代碼地址
- python官方os.path英文地址
- 本文最新版本地址
- os.path — Platform-independent Manipulation of Filenames
- os-path
- 本文涉及的python測試開發(fā)庫 謝謝點(diǎn)贊瞻凤!
- 本文相關(guān)海量書籍下載
構(gòu)建路徑
除了將現(xiàn)有的路徑分開之外憨攒,通常還需要從其他字符串構(gòu)建路徑。要將多個(gè)路徑組件合并請使用join():
import os.path
PATHS = [
('one', 'two', 'three'),
('/', 'one', 'two', 'three'),
('/one', '/two', '/three'),
]
for parts in PATHS:
print('{} : {!r}'.format(parts, os.path.join(*parts)))
執(zhí)行結(jié)果
$ python3 ospath_join.py
('one', 'two', 'three') : 'one/two/three'
('/', 'one', 'two', 'three') : '/one/two/three'
('/one', '/two', '/three') : '/three'
如果任何連接的參數(shù)以os.sep開始阀参,則所有先前的參數(shù)都將被丟棄肝集,新的參數(shù)將成為返回值的開始。
也可以使用包含可自動擴(kuò)展的“可變”組件的路徑蛛壳。例如杏瞻,expanduser() 將 ~轉(zhuǎn)換為用戶主目錄的名稱所刀。
# ospath_expanduser.py
import os.path
for user in ['', 'andrew', 'nosuchuser']:
lookup = '~' + user
print('{!r:>15} : {!r}'.format(
lookup, os.path.expanduser(lookup)))
執(zhí)行結(jié)果
'~' : '/home/andrew'
'~andrew' : '/home/andrew'
'~nosuchuser' : '~nosuchuser'
如果找不到用戶的主目錄,則字符串將以不變的形式返回伐憾,如本示例中的?nosuchuser一樣勉痴。
expandvars()更通用,它展開路徑中的所有shell環(huán)境變量树肃。
# ospath_expandvars.py
import os.path
import os
os.environ['MYVAR'] = 'VALUE'
print(os.path.expandvars('/path/to/$MYVAR'))
執(zhí)行結(jié)果
$ python3 ospath_expandvars.py
/path/to/VALUE
規(guī)范化路徑
使用join()或嵌入變量從不同的字符串匯編的路徑可能會以額外的分隔符或相對路徑組件結(jié)束蒸矛。使用normpath()來清理它們:
# ospath_normpath.py
import os.path
PATHS = [
'one//two//three',
'one/./two/./three',
'one/../alt/two/three',
]
for path in PATHS:
print('{!r:>22} : {!r}'.format(path, os.path.normpath(path)))
執(zhí)行結(jié)果
$ python3 ospath_normpath.py
'one//two//three' : 'one/two/three'
'one/./two/./three' : 'one/two/three'
'one/../alt/two/three' : 'alt/two/three'
要將相對路徑轉(zhuǎn)換為絕對文件名,請使用abspath()胸嘴。
# ospath_abspath.py
import os
import os.path
os.chdir('/usr')
PATHS = [
'.',
'..',
'./one/two/three',
'../one/two/three',
]
for path in PATHS:
print('{!r:>21} : {!r}'.format(path, os.path.abspath(path)))
執(zhí)行結(jié)果
$ python3 ospath_normpath.py
'one//two//three' : 'one/two/three'
'one/./two/./three' : 'one/two/three'
'one/../alt/two/three' : 'alt/two/three'
文件時(shí)間
除了使用路徑之外雏掠,os.path還包括用于檢索文件屬性的函數(shù),類似于os.stat()返回的函數(shù):
import os.path
import time
print('File :', __file__)
print('Access time :', time.ctime(os.path.getatime(__file__)))
print('Modified time:', time.ctime(os.path.getmtime(__file__)))
print('Change time :', time.ctime(os.path.getctime(__file__)))
print('Size :', os.path.getsize(__file__))
os.path.getatime()返回訪問時(shí)間劣像,os.path.getmtime()返回修改時(shí)間乡话,os.path.getctime()返回創(chuàng)建時(shí)間。 os.path.getsize()返回文件中的數(shù)據(jù)量耳奕,用字節(jié)表示绑青。
執(zhí)行結(jié)果
$ python3 ospath_properties.py
File : ospath_properties.py
Access time : Fri Aug 26 16:38:05 2016
Modified time: Fri Aug 26 15:50:48 2016
Change time : Fri Aug 26 15:50:49 2016
Size : 481
測試文件
當(dāng)程序遇到路徑名時(shí),通常需要知道路徑是指文件屋群,目錄還是符號鏈接闸婴,以及是否存在。 os.path包含測試所有這些條件的函數(shù)芍躏。
import os.path
FILENAMES = [
__file__,
os.path.dirname(__file__),
'/',
'./broken_link',
]
for file in FILENAMES:
print('File : {!r}'.format(file))
print('Absolute :', os.path.isabs(file))
print('Is File? :', os.path.isfile(file))
print('Is Dir? :', os.path.isdir(file))
print('Is Link? :', os.path.islink(file))
print('Mountpoint? :', os.path.ismount(file))
print('Exists? :', os.path.exists(file))
print('Link Exists?:', os.path.lexists(file))
print()
執(zhí)行結(jié)果
$ ln -s /does/not/exist broken_link
$ python3 ospath_tests.py
File : 'ospath_tests.py'
Absolute : False
Is File? : True
Is Dir? : False
Is Link? : False
Mountpoint? : False
Exists? : True
Link Exists?: True
File : ''
Absolute : False
Is File? : False
Is Dir? : False
Is Link? : False
Mountpoint? : False
Exists? : False
Link Exists?: False
File : '/'
Absolute : True
Is File? : False
Is Dir? : True
Is Link? : False
Mountpoint? : True
Exists? : True
Link Exists?: True
File : './broken_link'
Absolute : False
Is File? : False
Is Dir? : False
Is Link? : True
Mountpoint? : False
Exists? : False
Link Exists?: True