Python全栈工程师

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

2019-10-10  本文已影响0人  BeautifulSoulpy

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

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


参考:
你应该使用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'
上一篇下一篇

猜你喜欢

热点阅读