python庫介紹-os.path: 平臺獨(dú)立的文件名操作

目的:文件名和路徑解析埋泵,組合车份,測試等拂苹。

使用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

參考資料

構(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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末邪乍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子对竣,更是在濱河造成了極大的恐慌庇楞,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件否纬,死亡現(xiàn)場離奇詭異吕晌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)临燃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門聂使,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人谬俄,你說我怎么就攤上這事柏靶。” “怎么了溃论?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵屎蜓,是天一觀的道長。 經(jīng)常有香客問我钥勋,道長炬转,這世上最難降的妖魔是什么辆苔? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮扼劈,結(jié)果婚禮上驻啤,老公的妹妹穿的比我還像新娘。我一直安慰自己荐吵,他們只是感情好骑冗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著先煎,像睡著了一般贼涩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上薯蝎,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天遥倦,我揣著相機(jī)與錄音,去河邊找鬼占锯。 笑死袒哥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的消略。 我是一名探鬼主播堡称,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼疑俭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起婿失,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤钞艇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后豪硅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哩照,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年懒浮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了飘弧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出呢灶,到底是詐尸還是另有隱情自阱,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布澄暮,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏柱彻。R本人自食惡果不足惜豪娜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哟楷。 院中可真熱鬧瘤载,春花似錦、人聲如沸卖擅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽磨镶。三九已至溃蔫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間琳猫,已是汗流浹背伟叛。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脐嫂,地道東北人统刮。 一個(gè)月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像账千,于是被迫代替她去往敵國和親侥蒙。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容