21.4-Path对象路径基本操作——pathlib库

生活也许偶尔糟糕,但不能它糟你就糟。数学里负负得正,生活里负负会更负。

为了让这个得数负得不那么明显,麻烦你在生活糟糕的时候,也不要自怨自艾、自暴自弃,依然可以从容有序,不放弃每一点变好的努力。


参考:
你应该使用pathlib替代os.path

pathlib模块

Python 3.4引入了更好的路径处理方式:pathlib!支持不同的操作系统。我们只需要新建一个Path()对象,将路径或者文件传入,然后用/将它们连接即可,pathlib会帮我们做系统判断。

os.path 与 pathlib 模块对应关系

有两大类一个是纯路径不带I/0操作,另一个可以进行I/0的类。
总的来说,这些表示文件路径的类分为两类:纯路径 (pure paths) 和具体路径 (concrete path)。
纯路径对应的类是 PurePath,不包含 I/O 操作;具体路径对应的类是 Path ,继承自 PurePath,但包含了对该文件路径的 I/O操作。
pathlib 模块类继承关系

大多数情况下,我们都只需要使用 Path 这个类来对具体的文件路径进行操作,PurePath 这个类只在一些特殊情况会使用到,具体的情况可以参考 pathlib 的官方文档。下面,我通过对文件夹下的一堆 oracle dmp 文件的相关操作,来对比展现模块 pathlib 和 os.path 的差异。

总结:

  1. pathlib本质上调用的还是os.path() 对象 ;
  2. 不是所有的可迭代对象都支持负索引,
构建Path类路径对象

pathlib中不区分路径分隔符的,在win系统下可以直接用'/'。还可以用 / 创建子路径。感觉比直接字符串拼接和利用os.path.join()更加简洁;

  1. 类要求大写
from pathlib import Path,PurePath  # 类要求大写;
p = Path()   # 当前目录
p
#-----------------------------------
WindowsPath('.')

p = Path('a','b','c','d')  # 当前目录下的a/b/c/d
p0 = Path('/etc')    # g跟下的etc目录;
print(p.absolute())
#----------------------------------------------------------------
C:\Users\Administrator\Desktop\mage_edu\21 Python文件IO(二)文件操作\a\b\c\d

p = Path('a/b/c\d')
print(p.absolute())
#------------------------------------------------------------------
C:\Users\Administrator\Desktop\mage_edu\21 Python文件IO(二)文件操作\a\b\c\d


#直接传进一个完整字符串
p = Path('C:/Users/dongh/Documents/python_learn/pathlib_/file1.txt')

#也可以传进多个字符串
p = Path('C:\\', 'Users', 'dongh', 'Documents', 'python_learn', 'pathlib_', 'file1.txt')
#也可以利用Path.joinpath()
p = Path('C:/Users/dongh/Documents).joinpath('python_learn/pathlib_/file1.txt')
#PosixPath('C:/Users/dongh/Documents/python_learn/pathlib_/file1.txt')

#利用 / 可以创建子路径
p = Path('C:/Users/dongh/Documents)
p = p / 'python_learn/pathlib_/file1.txt'
print(p)
#PosixPath('C:/Users/dongh/Documents/python_learn/pathlib_/file1.txt')

了解对象基本情况

获取上一级路径

p = Path('C:/Users/dongh/Documents/python_learn/pathlib_/file1.txt')
#获取路径上一级目录路径
print(p.parent)#pathlib_\folder1
#获取上上一级目录路径
print(p.parent.parent)
#----------------------------------------------------------------------------------
C:\Users\dongh\Documents\python_learn\pathlib_
C:\Users\dongh\Documents\python_learn

获取路径组件名字(返回的是字符串)

str 获取路径字符串
bytes 获取路径字符串的bytes

bytes 是 str 的二进制文本模式

路径的不同部分可以方便地用作属性。 基本的例子包括:

.name : 没有任何目录的文件名
.parent: 包含该文件的目录,或者如果path是目录,则是父目录
.stem: 文件名不带后缀
.suffix: 文件扩展名
.anchor: 目录之前的路径部分
#获取当前路径文件名的后缀名
#获取当前路径文件名不带后缀
#获取当前路径文件名带后缀
print(p.suffix)
print(p.stem)
print(p.name)#pathlib_\folder1

p2 = p1 / 'test.tar.gz'
p2.name,p2.stem,p2.suffix,p2.suffixes
#-----------------------------------------------
('test.tar.gz', 'test.tar', '.gz', ['.tar', '.gz'])


#获取上一级目录路径名字
print(p.parent.name)
#获取上上一级目录路径名字
print(p.parent.parent.name)
#--------------------------------------------------------
.txt
file1
file1.txt
pathlib_
python_learn

str(p)
#---------------------------
'a'

bytes(p)
#---------------------------
b'a'

bytes(p) + b'\c'
#---------------------------
b'a\\c'

路径拼接

操作符/
Path对象 / Path对象
Path对象/字符串 或者 字符串/Path对象

p = Path('/etc','sysconfig','network/test')
p
#---------------------------------------------
WindowsPath('/etc/sysconfig/network/test')


p / 'c' / 'd'
#----------------------------------------------------------------------
WindowsPath('/etc/sysconfig/network/test/c/d')

p1 = p / 'c' / 'd' / 'e' / p
p1 
#----------------------------------
WindowsPath('c/d/e')
将路径分成不同组分(返回一个元组)
print(p.parts)
#--------------------------------------------------------
('C:\\', 'Users', 'dongh', 'Documents', 'python_learn', 'pathlib_', 'file1.txt')

joinpath

joinpath(*other) 链接多个字符串到Path对象中;

p = Path()
p = p/'a'
p1 = 'b'/p
p2 = Path('c')
p3 = p2 / p1
print(p3.parts)
p3.joinpath('etc','init.d',Path('httpd'))
#---------------------------------------------------------------------------
('c', 'b', 'a')
WindowsPath('c/b/a/etc/init.d/httpd')

深入了解对象

哈哈,简单了解对象的是不够的~~~万一对象不存在呢

判断对象属性 -
p.exists() 判断对象是否存在
p.is_file() 判断对象是否是文件
p.is_dir() 判断对象是否是目录
全局方法 -
cwd() 返回当前工作目录
home() 返回当前家目录

pathlib.Path 类。创建路径有几种不同的方式。首先,有类方法,如.cwd(当前工作目录)和.home(用户的主目录):

from pathlib import Path

now_path = Path.cwd()
home_path = Path.home()

print("当前工作目录",now_path,type(now_path))
print("home目录",home_path,type(home_path))
--------------------------------------------------------------------------
当前工作目录 C:\Users\Administrator\Desktop\mage_edu\21 Python文件IO(二)文件操作 <class 'pathlib.WindowsPath'>
home目录 C:\Users\Administrator <class 'pathlib.WindowsPath'>

实例、对象、类的方法

方法
p.chmod(777) 修改目录权限
a.read_text() # 读取文件内容
(a.name) # prints "Iris.csv" 获取文件名
a.suffix #prints ".csv" 获取后缀
a.parts # ('data', 'data2', 'Iris.csv') # 分离路径
rmdir() 删除目录
exists() 目录或文件是否存在
p.resolve() # 将路径绝对化
Path.home() # home路径
p.with_name('sibling.png') # 只修改拓展名, 不会修改源文件
p.with_suffix('.jpg') # 只修改拓展名, 不会修改源文件
判断方法

存在的东西才可以判断

方法
p.is_dir() # 判断是否为目录
p.is_file() # 判断是否为文件夹
p.is_symlink() # 判断是否为软连接
p.is_socket() # 判断是否为socket文件
p.is_block_device() # 判断是否为块设备
p.is_char_device() # 判断是否是字符设备
p.is_absolute() # 判断是否为绝对路径
- -
Path('./tet1.txt').touch() 创建文件对象(Linux下会有权限)
touch(mode=0o666,exits_ok=True) 创建一个文件
resolve() 返回一个新的路径,为当前Path对象的绝对路径,如果是软连接则直接被解析
absolute() 获取绝对路径
rmdir() 删除空目录,没有提供判断目录为空的方法
as_uri 将路径返回成URI,例如'file://etc/passwd'
p.mkdir(mode=511, parents=False, exist_ok=False) 创建目录,参数exist_ok 3.5才有的
iterdir() 迭代目录中的文件(带. 文件) list(Path('./tmp').iterdir()),[WindowsPath('tmp/test.txt'), WindowsPath('tmp/test1.txt')]
# 遍历并判断文件类型,如果是目录是否可以判断其是否为空?
for x in p.parents[len(p.parents)-1].iterdir():
    print(x,end='\t')
    if x.is_dir():
        flag = False
        for _ in x.iterdir():
            flag = True
            break     
        # for 循坏是否可以使用else子句;
        print('dir','Not Empty' if flag else 'Empyt',sep='\t')
    elif x.is_file():
        print('file')
    else:
        print('other file')
#----------------------------------------------------------------------------
.ipynb_checkpoints  dir Not Empty
21.1-习题base64解码.ipynb   file
21.2-习题命令分发器、copy和单词统计.ipynb    file
21.3-StringIO和BytesIO和os.path.ipynb file
21.4-Path对象基本操作——pathlib模块.ipynb    file
sample.txt  file
tet1.txt    file
text.py file
tmp dir Not Empty

取上级目录的内部实现
p.absolute().parents[len(p.absolute().parents)-1].iterdir()
#----------------------------------------------------------------------------------
<generator object Path.iterdir at 0x000001E18EAAD5E8>

遍历文件夹下的路径

#p指向的是一个文件不是文件夹。它的上一级才是文件
for i in p.parent.iterdir():
    print(i,)
"""
C:\Users\dongh\Documents\python_learn\pathlib_\file1
C:\Users\dongh\Documents\python_learn\pathlib_\file2
C:\Users\dongh\Documents\python_learn\pathlib_\folder1
C:\Users\dongh\Documents\python_learn\pathlib_\folder2
C:\Users\dongh\Documents\python_learn\pathlib_\folder3
C:\Users\dongh\Documents\python_learn\pathlib_\test.py
C:\Users\dongh\Documents\python_learn\pathlib_\file1.txt
"""

for x in p.parents[len(p.parents)-1].iterdir():
    print(x)
#----------------------------------------------------------------------------------
.ipynb_checkpoints
21.1-习题base64解码.ipynb
21.2-习题命令分发器、copy和单词统计.ipynb
21.3-StringIO和BytesIO和os.path.ipynb
21.4-Path对象基本操作——pathlib模块.ipynb
sample.txt
tet1.txt
text.py
tmp


In : p = Path('/Users/dongweiming/test')
In : p.parents[0]
Out: PosixPath('/Users/dongweiming')

In : p.parents[1]
Out: PosixPath('/Users')

In : p.parents[2]
Out: PosixPath('/')

In : p.parent
Out: PosixPath('/Users/dongweiming')

In : p.parent.parent
Out: PosixPath('/Users')



for x in p.absolute().parents[len(p.absolute().parents)-1].iterdir():
    print(x)
#----------------------------------------------------------------------------------
C:\$RECYCLE.BIN
C:\$WINDOWS.~BT
C:\$Windows.~WS
C:\360SANDBOX
C:\Boot
C:\bootmgr
C:\BOOTNXT
C:\Documents and Settings
C:\DrvPath
C:\inetpub
C:\pagefile.sys
C:\Program Files
C:\Program Files (x86)
C:\ProgramData
C:\Recovery
C:\swapfile.sys
C:\System Volume Information
C:\Temp
C:\test.txt
C:\Users
C:\Windows

有目的寻找

#* 表示匹配任意字符串,但这只能在当前目录下寻找
for i in p.parent.glob('*.txt'): 
   print(i)
#-------------------------------------------------------------------
C:\Users\dongh\Documents\python_learn\pathlib_\file1.txt
C:\Users\dongh\Documents\python_learn\pathlib_\file2.txt


#寻找当前路径的下一路径的内容
for i in p.parent.glob('*/*.txt'):    
   print(i)
#--------------------------------------------------------------------------------------------------
C:\Users\dongh\Documents\python_learn\pathlib_\folder1\folder_file1.txt
C:\Users\dongh\Documents\python_learn\pathlib_\folder2\folder2.txt


#寻找当前路径下所有符合条件文件
#' ** '意思当前路径和它的所有子路径,相当于循环匹配一遍子路径
#和Path.rglob()效果一样
for i in p.parent.glob('**/*.txt'):#for i in p.parent.rglob('*.txt') 
   print(i)
#-----------------------------------------------------------------------------
C:\Users\dongh\Documents\python_learn\pathlib_\file1.txt
C:\Users\dongh\Documents\python_learn\pathlib_\file2.txt
C:\Users\dongh\Documents\python_learn\pathlib_\folder1\folder_file1.txt
C:\Users\dongh\Documents\python_learn\pathlib_\folder1\sub_folder1\sub_file1.txt
C:\Users\dongh\Documents\python_learn\pathlib_\folder2\folder2.txt

对对象动点手脚

写入数据

#写入二进制数据
p.write_bytes(b'hello world!')
#写入文本
p.write_text('hello world!')
#------------------------------------------------
'hello world!'

读取数据

#读二进制数据
print(p.read_bytes())
#b'hello world!'

#读文本
p.read_text()
#'hello world!'

Path.open()和内置open()差不多

    print(f.read())
#hello world!
with p.open('w') as f:
    f.write('hello again!')

给对象改个名字

p.rename('new_file.txt')
#原来的'file1.txt'被改成new_file.txt',文件内的内容不变。

创造新的路径

p.mkdir()
#将创建一个名为p.name的新文件夹。
p.rmdir()
#将删除这个文件夹,它必须是空的才能够删除

判断文件是否一样

print(p.samefile('file1.txt'))
#返回True

改变新的路径或后缀名并返回新的路径(原来的路径不被改变)

print(p.with_name('new_file1.txt'))
#--------------------------------------------------
'C:/Users/dongh/Documents/python_learn/pathlib_/new_file1.txt'
print(p.with_suffix('.csv'))
#--------------------------------------------------
'C:/Users/dongh/Documents/python_learn/pathlib_/file1.csv'
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,176评论 5 469
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,190评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,232评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,953评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,879评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,177评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,626评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,295评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,436评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,365评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,414评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,096评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,685评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,771评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,987评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,438评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,032评论 2 341