每周一個(gè) Python 模塊 | os.path

本文基于 Python3 編寫測(cè)試。

os.path 模塊是跨平臺(tái)的,即使不打算在平臺(tái)之間移植自己的程序也應(yīng)該用 os.path,好處多多。

解析路徑

第一組 os.path 函數(shù)可用于將表示文件名的字符串解析為其組成部分。重要的是要意識(shí)到這些功能不依賴于實(shí)際存在的路徑。

路徑解析取決于以下定義的一些 os 變量:

  • os.sep- 路徑部分之間的分隔符(例如,“ /”或“ \”)。
  • os.extsep- 文件名和文件“擴(kuò)展名”之間的分隔符(例如,“ .”)。
  • os.pardir- 路徑組件,意味著將目錄樹向上遍歷一級(jí)(例如,“ ..”)。
  • os.curdir- 引用當(dāng)前目錄的路徑組件(例如,“ .”)。

split() 函數(shù)將路徑分成兩個(gè)獨(dú)立的部分,并返回一個(gè)tuple結(jié)果。第二個(gè)元素是路徑的最后一個(gè)元素,第一個(gè)元素是它之前的所有元素。

import os.path

PATHS = [
    '/one/two/three',
    '/one/two/three/',
    '/',
    '.',
    '',
]

for path in PATHS:
    print('{!r:>17} : {}'.format(path, os.path.split(path)))
    
# output
# '/one/two/three' : ('/one/two', 'three')
# '/one/two/three/' : ('/one/two/three', '')
#               '/' : ('/', '')
#               '.' : ('', '.')
#                '' : ('', '')

當(dāng)輸入?yún)?shù)以 os.sep 結(jié)束時(shí),路徑的最后一個(gè)元素是一個(gè)空字符串。

basename()函數(shù)返回一個(gè)等于 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)))
    
# output
# '/one/two/three' : 'three'
# '/one/two/three/' : ''
#               '/' : ''
#               '.' : '.'
#                '' : ''

完整路徑被剝離到最后一個(gè)元素,無論是指文件還是目錄。

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)))
    
# output
# '/one/two/three' : '/one/two'
# '/one/two/three/' : '/one/two/three'
#               '/' : '/'
#               '.' : ''
#                '' : ''

結(jié)合basename()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)))
    
# output
#        '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', '.')

os.extsep在查找擴(kuò)展名時(shí)僅匹配最后一次出現(xiàn)的分隔符,因此如果文件名具有多個(gè)擴(kuò)展名,則會(huì)按照最后一個(gè)擴(kuò)展名進(jìn)行拆分。

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))

# output
# PATH: /one/two/three/four
# PATH: /one/two/threefold
# PATH: /one/two/three/
# 
# PREFIX: /one/two/three

在此示例中,公共前綴字符串是/one/two/three,即使一個(gè)路徑不包含名為的目錄three

commonpath() 考慮路徑分隔符,并返回不包含部分路徑值的前綴。

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))

# output
# PATH: /one/two/three/four
# PATH: /one/two/threefold
# PATH: /one/two/three/
# 
# PREFIX: /one/two

構(gòu)建路徑

除了將現(xiàn)有路徑分開之外,經(jīng)常需要從其他字符串構(gòu)建路徑。要將多個(gè)路徑組合為單個(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)))
    
# output
# ('one', 'two', 'three') : 'one/two/three'
# ('/', 'one', 'two', 'three') : '/one/two/three'
# ('/one', '/two', '/three') : '/three'

如果有任何一個(gè)參數(shù)是以 os.sep 開頭的,則先前所有的參數(shù)都會(huì)被丟棄,并將該值作為返回值的開頭。

也可以使用包含可以自動(dòng)擴(kuò)展的“可變”組件的路徑。例如,expanduser()~ 字符轉(zhuǎn)換為用戶主目錄的名稱。

import os.path

for user in ['', 'dhellmann', 'nosuchuser']:
    lookup = '~' + user
    print('{!r:>15} : {!r}'.format(lookup, os.path.expanduser(lookup)))
    
# output
#             '~' : '/Users/dhellmann'
#    '~dhellmann' : '/Users/dhellmann'
#   '~nosuchuser' : '~nosuchuser'

如果找不到用戶的主目錄,則返回字符串不變,如~nosuchuser。

expandvars() 更通用,擴(kuò)展路徑中存在的任何 shell 環(huán)境變量。

import os.path
import os

os.environ['MYVAR'] = 'VALUE'

print(os.path.expandvars('/path/to/$MYVAR'))    # /path/to/VALUE

并不會(huì)驗(yàn)證文件或路徑是否存在。

規(guī)范化路徑

使用join() 組合的路徑可能會(huì)有額外的分隔符或相對(duì)路徑。用 normpath()來清理它們:

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)))
    
# output
#      'one//two//three' : 'one/two/three'
#    'one/./two/./three' : 'one/two/three'
# 'one/../alt/two/three' : 'alt/two/three'

要將相對(duì)路徑轉(zhuǎn)換為絕對(duì)文件名,請(qǐng)使用 abspath()。

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)))
    
# output
#                   '.' : '/usr'
#                  '..' : '/'
#     './one/two/three' : '/usr/one/two/three'
#    '../one/two/three' : '/one/two/three'

文件時(shí)間

除了使用路徑之外,os.path還包括用于檢索文件屬性的函數(shù),類似于 os.stat()

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__))

# output
# File         : ospath_properties.py
# Access time  : Sun Mar 18 16:21:22 2018
# Modified time: Fri Nov 11 17:18:44 2016
# Change time  : Fri Nov 11 17:18:44 2016
# Size         : 481

os.path.getatime()返回訪問時(shí)間, os.path.getmtime()返回修改時(shí)間,os.path.getctime()返回創(chuàng)建時(shí)間。 os.path.getsize()返回文件中的數(shù)據(jù)量,以字節(jié)為單位表示。

測(cè)試文件

當(dāng)程序遇到路徑名時(shí),通常需要知道路徑是指文件,目錄還是符號(hào)鏈接以及它是否存在。 os.path包括測(cè)試所有這些條件的功能。

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()
    
# output
# 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

所有測(cè)試函數(shù)都返回布爾值。

相關(guān)文檔:

https://pymotw.com/3/os.path/index.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,721評(píng)論 0 5
  • 一、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 6,340評(píng)論 0 10
  • Pythos中調(diào)用操作系統(tǒng)的模塊,提供對(duì)操作系統(tǒng)進(jìn)行調(diào)用的接口 API方法 os.getcwd() 獲取當(dāng)前工作目...
    So_ProbuING閱讀 2,349評(píng)論 0 4
  • os.path.abspath(path) #返回絕對(duì)路徑,和realpath有區(qū)別,realpath是返回文件真...
    jova_y閱讀 848評(píng)論 0 1
  • 你會(huì)焦慮嗎 最近焦慮感越來越敏感了 只要一不寫感恩日記 那個(gè)白天就很想發(fā)火 又或許沒有及時(shí)補(bǔ)充維生素,脾氣也莫名的...
    金蘭幸福旅程閱讀 179評(píng)論 0 0

友情鏈接更多精彩內(nèi)容