生活也许偶尔糟糕,但不能它糟你就糟。数学里负负得正,生活里负负会更负。
为了让这个得数负得不那么明显,麻烦你在生活糟糕的时候,也不要自怨自艾、自暴自弃,依然可以从容有序,不放弃每一点变好的努力。
参考:
你应该使用pathlib替代os.path
pathlib模块
Python 3.4引入了更好的路径处理方式:pathlib!支持不同的操作系统。我们只需要新建一个Path()对象,将路径或者文件传入,然后用/将它们连接即可,pathlib会帮我们做系统判断。
有两大类一个是纯路径不带I/0操作,另一个可以进行I/0的类。
总的来说,这些表示文件路径的类分为两类:纯路径 (pure paths) 和具体路径 (concrete path)。
纯路径对应的类是 PurePath,不包含 I/O 操作;具体路径对应的类是 Path ,继承自 PurePath,但包含了对该文件路径的 I/O操作。
大多数情况下,我们都只需要使用 Path 这个类来对具体的文件路径进行操作,PurePath 这个类只在一些特殊情况会使用到,具体的情况可以参考 pathlib 的官方文档。下面,我通过对文件夹下的一堆 oracle dmp 文件的相关操作,来对比展现模块 pathlib 和 os.path 的差异。
总结:
- pathlib本质上调用的还是os.path() 对象 ;
- 不是所有的可迭代对象都支持负索引,
构建Path类路径对象
pathlib中不区分路径分隔符的,在win系统下可以直接用'/'。还可以用 / 创建子路径。感觉比直接字符串拼接和利用os.path.join()更加简洁;
- 类要求大写
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'