Python 目录操作
[摘要] 主要内容:windows/linux下路径操作,介绍os.path和pathlib.Path两个模块,路径拼接和拆解(操作符,分解),joinpath,获取路径,父目录,其它目录操作方法,通配符,匹配。
os.path 路径操作 (3.4之前)
pathlib.Path (3.4之后推荐使用的模块)
3.4 版本之前
使用标准库os.path 模块
#linux下与windows下的默认路径分隔符不同
#linux下
In [1]: from os import path
In [2]: p = path.join('/etc','sysconfig','network')
In [3]: p
Out[3]: '/etc/sysconfig/network' #linux默认是'/'为路径分隔符
In [7]: os.name
Out[7]: 'posix'
#windows下
In [1]: from os import path
In [2]: p = path.join('/etc','sysconfig','network')
In [3]: p
Out[3]: '/etc\\sysconfig\\network' #windows是'\'反斜杠,'\\’是对'\'转义
In [15]: os.name
Out[15]: 'nt'
以下内容将全部以windows下为主,与linux大同小异,只需要注意路径的写法,nt表示windows,posix表示linux即可,windows是以驱动器为起始路径,linux是以'/'为起始路径。
os.path模块常用方法:
In [34]: from os import path #导入path模块
In [35]: p = path.join('/etc','sysconfig','network') #拼接一个path
In [36]: p
Out[36]: '/etc\\sysconfig\\network'
In [37]: type(p)
Out[37]: str
In [38]: path.exists(p) #判断'p'这个path路径在当前系统下是否存在
Out[38]: False
In [39]: path.split(p) #将path分割为两部分(head,tail),tail为最后一个路径
Out[39]: ('/etc\\sysconfig', 'network')
In [40]: p1 = '.' #'.'表示当前目录
In [41]: path.abspath(p1) #返回指定path的绝对路径
Out[41]: 'C:\\Users\\admin\\Desktop\\fileDir'
In [43]: p2 = 'abc'
In [44]: path.abspath(p2)
Out[44]: 'C:\\Users\\admin\\Desktop\\fileDir\\abc'
In [45]: p3 = path.abspath(p2)
In [46]: path.dirname(p3) #目录路径
Out[46]: 'C:\\Users\\admin\\Desktop\\fileDir'
In [47]: path.basename(p3) #文件基名
Out[47]: 'abc'
In [48]: p3
Out[48]: 'C:\\Users\\admin\\Desktop\\fileDir\\abc'
In [49]: path.splitdrive(p3) #windows下返回 drive/UNC 路径
Out[49]: ('C:', '\\Users\\admin\\Desktop\\fileDir\\abc')
其它一些方法:
os.path.isabs(path) #是否是绝对路径,返回True或False
os.path.isfile(path) #是否是文件
os.path.isdir(path) #是否是目录
os.path.islink(path) #是否是链接文件,linux下的软连接和硬链接
os.path.ismount(path) #是否是挂载文件
3.4 版本之后
3.4 版本之后则建议使用pathlib 模块,提供Path 对象来操作。包括目录和文件。
from pathlib import Path 导入
#windows下:
In [50]: from pathlib import Path #Path的'p'注意大写
In [51]: p = Path() #路径初始化
In [52]: p
Out[52]: WindowsPath('.')
In [53]: print(type(p))
<class 'pathlib.WindowsPath'> #与linux不同
In [54]: p.absolute()
Out[54]: WindowsPath('C:/Users/admin/Desktop/fileDir')
#linux下:
In [1]: from pathlib import Path #Path的'p'注意大写
In [2]: p = Path()
In [3]: p
Out[3]: PosixPath('.')
In [4]: type(p)
Out[4]: pathlib.PosixPath #对比与winodws的不同
In [5]: p.absolute()
Out[5]: PosixPath('/home/python/magedu/project/cmdb')
In [7]: p.joinpath('a','b')
Out[7]: PosixPath('a/b')
In [8]: p.absolute()
Out[8]: PosixPath('/home/python/magedu/project/cmdb')
In [9]: p = p.joinpath('a','b') #等同于os.path.join()方法,连接路径
In [10]: p.absolute() #linux默认以'/'默认路径分隔符
Out[10]: PosixPath('/home/python/magedu/project/cmdb/a/b')
In [11]: p = p / 'c' / 'd' #路径拼接方法
In [12]: p
Out[12]: PosixPath('a/b/c/d')
In [13]: p /= 'e' #第二种路径拼接,简写成'/='
In [14]: p
Out[14]: PosixPath('a/b/c/d/e')
In [17]: p2 = '/etc' / 'sysconfig' #'str'和'str'不能用'/'连接
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-17-cf6a25c9c496> in <module>()
----> 1 p2 = '/etc' / 'sysconfig'
TypeError: unsupported operand type(s) for /: 'str' and 'str'
In [18]: p2 = '/etc' + 'sysconfig' #符号 ’+’ 可以连接,但就不是path路径了,而是字符串
In [19]: p2
Out[19]: '/etcsysconfig'
In [20]: p2 = Path('') #路径可以为空,表示当前路径
In [21]: p2
Out[21]: PosixPath('.')
In [23]: p2 = p2 / '/etc/' / 'sysconfig'
In [24]: p2
Out[24]: PosixPath('/etc/sysconfig')
In [26]: p2 /= '.'
In [27]: p2
Out[27]: PosixPath('/etc/sysconfig')
In [28]: p3 = Path('a','b','c')
In [29]: p3
Out[29]: PosixPath('a/b/c')
In [30]: p3 = Path('/a','/b','/c') #注意连接路径时linux下不要加'/'符号,否则就表示根目录下的'/a'目录了
In [31]: p3
Out[31]: PosixPath('/c') #否则只会保存最后一个以'/'开头的path
In [32]: p3 = Path('/a','/b','c') #同样
In [33]: p3
Out[33]: PosixPath('/b/c')
路径初始化:
In [32]: p = Path() #当前目录
In [33]: p
Out[33]: PosixPath('.')
In [34]: p = Path('a','b','c/d') #当前目录下的a/b/c/d
In [35]: p
Out[35]: PosixPath('a/b/c/d')
In [36]: p = Path('/etc') #根目录下的etc目录
In [37]: p
Out[37]: PosixPath('/etc')
In [38]: p = Path('/a','b','c/d') #根目录下的/a/b/c/d目录
In [39]: p
Out[39]: PosixPath('/a/b/c/d')
路径拼接和拆解
操作符 /
Path对象 / Path对象
Path对象 / 字符串 或者 字符串 / Path对象
In [41]: p
Out[41]: PosixPath('.')
In [42]: p.absolute()
Out[42]: PosixPath('/home/python/magedu/project/cmdb')
In [43]: p = p / 'a'
In [44]: p
Out[44]: PosixPath('a')
In [45]: p.absolute()
Out[45]: PosixPath('/home/python/magedu/project/cmdb/a')
分解
parts属性,可以返回路径中的每一个部分
In [47]: p2 = Path('/etc','sysconfig')
In [48]: p2
Out[48]: PosixPath('/etc/sysconfig')
In [50]: p2.parts
Out[50]: ('/', 'etc', 'sysconfig')
In [51]: str(p2.parts)
Out[51]: "('/', 'etc', 'sysconfig')"
In [52]: str(p2.parts) + '/abc/d'
Out[52]: "('/', 'etc', 'sysconfig')/abc/d"
In [53]: str(p2) + '/abc/d'
Out[53]: '/etc/sysconfig/abc/d'
In [54]: p2 + 'a'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-54-43da11262e30> in <module>()
----> 1 p2 + 'a'
TypeError: unsupported operand type(s) for +: 'PosixPath' and 'str'
joinpath
joinpath(*other) 连接多个字符串到Path对象中
In [59]: p = Path()
In [60]: p
Out[60]: PosixPath('.')
In [61]: p = p / 'a'
In [62]: p1 = 'b' / p
In [63]: p2 = Path('c')
In [64]: p3 = p2 / p1
In [65]: print(p3.parts)
('c', 'b', 'a')
In [66]: p3.joinpath('/etc','init.d',Path('nginx'))
Out[66]: PosixPath('/etc/init.d/nginx')
In [67]: p
Out[67]: PosixPath('a')
In [68]: p1
Out[68]: PosixPath('b/a')
In [69]: p2
Out[69]: PosixPath('c')
In [70]: p3
Out[70]: PosixPath('c/b/a')
获取路径
str 获取路径字符串
bytes 获取路径字符串的bytes
In [71]: p = Path('/etc')
In [72]: print(str(p),bytes(p))
/etc b'/etc'
父路径(父目录)
parent 目录的逻辑父目录
parents 父目录序列,索引0是直接的父
In [75]: p2 = Path('/etc','sysconfig')
In [76]: p2
Out[76]: PosixPath('/etc/sysconfig')
In [77]: p2.encode()
...........
AttributeError: 'PosixPath' object has no attribute 'encode'
In [79]: str(p2).encode() #转为str再转bytes
Out[79]: b'/etc/sysconfig'
In [80]: bytes(p2)
Out[80]: b'/etc/sysconfig'
In [81]: p2.parts
Out[81]: ('/', 'etc', 'sysconfig')
In [85]: p2.parents
Out[85]: <PosixPath.parents>
In [86]: p2.parent #返回每一级的父目录
Out[86]: PosixPath('/etc')
In [87]: p2.parent.parent
Out[87]: PosixPath('/')
In [88]: p2.parent.parent.parent
Out[88]: PosixPath('/')
In [89]: p2.parent.parent.parent.parent #linux最高父目录只能是'/'根,
Out[89]: PosixPath('/')
In [92]: p3 /= 'a/b/c/d'
In [93]: list(p3.parents)
Out[93]:
[PosixPath('c/b/a/a/b/c'),
PosixPath('c/b/a/a/b'),
PosixPath('c/b/a/a'),
PosixPath('c/b/a'),
PosixPath('c/b'),
PosixPath('c'),
PosixPath('.')]
In [94]: p3
Out[94]: PosixPath('c/b/a/a/b/c/d')
In [95]: del p3
In [96]: p
Out[96]: PosixPath('/etc')
In [106]: p3 = Path('/etc') / 'sysconfig' / 'a/b/c/d'
In [107]: p3
Out[107]: PosixPath('/etc/sysconfig/a/b/c/d')
In [108]: list(p3.parents) #列表格式返回所有每一级父路径
Out[108]:
[PosixPath('/etc/sysconfig/a/b/c'),
PosixPath('/etc/sysconfig/a/b'),
PosixPath('/etc/sysconfig/a'),
PosixPath('/etc/sysconfig'),
PosixPath('/etc'),
PosixPath('/')]
In [109]: list(p3.parents)[2] #既然是列表就可以用索引
Out[109]: PosixPath('/etc/sysconfig/a')
In [110]: list(p3.parents)[-1]
Out[110]: PosixPath('/')
In [129]: p4 = Path()
In [130]: p4.absolute()
Out[130]: PosixPath('/home/python/magedu/project/cmdb')
In [131]: p4.absolute().parents
Out[131]: <PosixPath.parents>
In [132]: list(p4.absolute().parents) #绝对路径的每一级父路径
Out[132]:
[PosixPath('/home/python/magedu/project'),
PosixPath('/home/python/magedu'),
PosixPath('/home/python'),
PosixPath('/home'),
PosixPath('/')]
其它方法:
name、stem、suffix、suffixes、whth_suffix(suffix)、with_name(name)
name 目录的最后一个部分
suffix 目录中最后一个部分的扩展名
stem 目录最后一个部分,没有后缀
suffixes 返回多个扩展名列表
with_suffix(suffix) 补充扩展名到路径尾部,返回新的路径,扩展名存在则无效
with_name(name) 替换目录最后一个部分并返回一个新的路径
In [135]: p5 = Path('/etc/sysconfig/network/xxx.tar.gz')
In [136]: p5.stem
Out[136]: 'xxx.tar'
In [137]: p5.name
Out[137]: 'xxx.tar.gz'
In [138]: p5.suffix
Out[138]: '.gz'
In [139]: p5.suffixes
Out[139]: ['.tar', '.gz']
In [140]: p5.with_suffix('gz')
........略
ValueError: Invalid suffix 'gz'
In [141]: p5.with_suffix('.gz') #当前就是'.gz'后缀,看不到效果
Out[141]: PosixPath('/etc/sysconfig/network/xxx.tar.gz')
In [142]: p5.with_suffix('.jz') #替换为'.jz'
Out[142]: PosixPath('/etc/sysconfig/network/xxx.tar.jz')
In [144]: p5.with_suffix('.zip') #替换为'.zip'
Out[144]: PosixPath('/etc/sysconfig/network/xxx.tar.zip')
In [145]: p5
Out[145]: PosixPath('/etc/sysconfig/network/xxx.tar.gz')
In [146]: p5.with_name('yyy.txt') #替换文件名'yyy.txt'
Out[146]: PosixPath('/etc/sysconfig/network/yyy.txt')
In [147]: p5.with_name('zzz.txt')
Out[147]: PosixPath('/etc/sysconfig/network/zzz.txt')
In [155]: p3 = Path('/etc/sysconfig/network/back.tar.gz')
In [164]: p5.with_name(p3.name)
Out[164]: PosixPath('/etc/sysconfig/network/back.tar.gz')
cwd() 返回当前工作目录
home() 返回当前家目录
is_dir() 是否是目录
is_file() 是否是普通文件
is_symlink() 是否是软链接
is_socket() 是否是socket文件
is_block_device() 是否是块设备
is_char_device() 是否是字符设备
is_absolute() 是否是绝对路径
resolve() 返回一个新的路径,这个路径就是当前Path对象的绝对路径,如果是软链接则直接被解析
absolute() 也可以获取绝对路径,但是推荐使用resolve()
exists() 目录或文件是否存在
move() 移动目录或文件
rmdir() 删除空目录。没有提供判断目录为空的方法
touch(mode=0o666,exist_ok=True) 创建一个文件
as_uri() 将路径返回URI,例如'file:///etc/password'
mkdir(mode=0o755,parents=False,esist_ok=False)
parents,是否创建父目录,True等同于mkdir -p;Flase时,父目录不存在,抛出异常 FileNotFoundError
exist_ok 参数,在3.5版本加入。False时,路径存在,抛出FileExistsError;True时,FileExistsError被忽略
iterdir()
迭代当前目录
以上各种方法举例:
In [172]: p6 = Path()
In [173]: p6
Out[173]: PosixPath('.')
In [175]: p6.cwd()
Out[175]: PosixPath('/home/python/magedu/project/cmdb')
In [176]: p6.home()
Out[176]: PosixPath('/home/python')
In [183]: p6 = Path('log')
In [184]: p6
Out[184]: PosixPath('log')
In [185]: p6.exists()
Out[185]: False
In [187]: p6.mkdir(mode=0o777,parents=False,exist_ok=False) #创建这个log目录,0o表示8进制(0x,16进制,0b,2进制),777表示权限(rwx)
In [188]: ls
log/
In [195]: p7 = Path('1.txt')
In [196]: p7.touch(mode=0o666,exist_ok=True) #创建这个文件,如果文件已存在,会将修改时间更新为当前时间
In [197]: ls
1.txt log/
In [198]: p7.touch(mode=0o666,exist_ok=False) #如果文件已存在,返回异常 FileExistsError
.......略
FileExistsError: [Errno 17] File exists: '1.txt'
In [27]: shutil.move('/home/python/copyfile.txt','/home/python/magedu/project/cmdb/copyfile.txt')
Out[27]: '/home/python/magedu/project/cmdb/copyfile.txt'
In [28]: ls
copyfile.txt
通配符
glob(pattern) 通配给定的模式
rglob(pattern) 通配给定的模式,递归目录
举例:
list(p6.glob('*.conf')) #仅查找当前目录下'.conf'结尾的配置文件
list(p6.glob('**/*.conf')) #递归'/etc'下所有目录查找'.conf'结尾的配置文件
list(p6.rglob('*.conf')) #也是递归查找,等同于list(p6.glob('**/*.conf'))
In [213]: list(p6.glob('*.conf')) #仅查找当前目录下'.conf'结尾的配置文件
Out[213]:
[PosixPath('/etc/resolv.conf'),
PosixPath('/etc/yum.conf'),
PosixPath('/etc/host.conf'),
....略
PosixPath('/etc/rsyncd.conf'),
PosixPath('/etc/fprintd.conf'),
PosixPath('/etc/ntp.conf')]
In [214]: list(p6.glob('**/*.conf')) #递归'/etc'下索引目录查找'.conf'结尾的配置文件
Out[214]:
[PosixPath('/etc/resolv.conf'),
PosixPath('/etc/libuser.conf'),
PosixPath('/etc/yum.conf'),
PosixPath('/etc/dracut.conf'),
PosixPath('/etc/host.conf'),
....略
PosixPath('/etc/security/pam_env.conf'),
PosixPath('/etc/security/sepermit.conf'),
PosixPath('/etc/security/time.conf'),
PosixPath('/etc/plymouth/plymouthd.conf'),
PosixPath('/etc/tuned/tuned-main.conf')]
In [215]: list(p6.rglob('*.conf')) #等同于list(p6.glob('**/*.conf'))
Out[215]:
[PosixPath('/etc/resolv.conf'),
PosixPath('/etc/yum.conf'),
PosixPath('/etc/host.conf'),
PosixPath('/etc/sysctl.conf'),
PosixPath('/etc/ntp.conf'),
PosixPath('/etc/depmod.d/dist.conf'),
....略
PosixPath('/etc/abrt/abrt.conf'),
PosixPath('/etc/security/chroot.conf'),
PosixPath('/etc/security/group.conf'),
PosixPath('/etc/security/limits.conf')]
匹配
match(pattern)
模式匹配,成功返回True
Path('a/b.py').match('*.py') # True
Path('/a/b/c.py').match('b/*.py') # True
Path('/a/b/c.py').match('a/*.py') # False
Path('/a/b/c.py').match('a/**.py') # False
Path('/a/b/c.py').match('a/*/*.py') #True
Path('/a/b/c.py').match('a**.py') # False
Path('/a/b/c.py').match('a**/*.py') # False
Path('/a/b/c.py').match('a/**/*.py') # True
Path('/a/b/c.py').match('**/*.py') #True
windows/linux下路径操作,介绍os.path和pathlib.Path两个模块,路径拼接和拆解(操作符,分解),joinpath,获取路径,父目录,其它目录操作方法,通配符,匹配。

浙公网安备 33010602011771号