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,获取路径,父目录,其它目录操作方法,通配符,匹配。

 

posted @ 2017-10-26 16:36  ihoneysec  阅读(650)  评论(0编辑  收藏  举报