pathlib

这是一个在os.path库的基础上做进一步的高级封装后的库,它将路径字符串封装为一个path对象,进而将os单纯的路径字符串的处理变成了对一个路径字符串的path对象的处理,使用面向对象的处理方式,可以更加方便,更加灵活的对应对各种需求,方便开发者使用。

path对象

PurePath类是 所有Path类的父类,Path 类继承于 PurePath 类,Path可以使用从 PurePath类继承的方法和属性,例如parent,is_abusolute()等方法。并在PurePath类的基础上做了一些扩展方法,因此直接使用Path对象即可。

python 加入pythonpath 脚本所在目录 pythonpath添加路径_绝对路径

 

windowsPath和PosixPath

由于 Windows 操作系统 和 Linux 操作系统 文件系统设计存差异。路径字符串的表示方法有所不同,例如Linux 使用 “ / ” 分隔符而 Windows 使用 “ \ ”,根目录表示方式也不同。因此针对两套系统创建了WindowsPath类 和 PosixPath类。

在 Windows 操作系统下,默认创建的 Path 对象是 WindowsPath 对象,其余Linux,unix 等满足 POSIX 规范的操作系统都将被创建为 PosixPath 对象。

class Path(PurePath):
    def __new__(cls, *args, **kwargs):
        if cls is Path:
            cls = WindowsPath if os.name == 'nt' else PosixPath
             # 使用os判断系统类型,创建不同类型的实例对象  
        self = cls._from_parts(args, init=False)
        if not self._flavour.is_supported:
            raise NotImplementedError(
        "cannot instantiate %r on your system" % (cls.__name__,))
        self._init()
        return self

创建Path对象

创建一个 path 对象非常简单,只需要向Path 类传入一个路径字符串,变可以得到这个路径对应的 path 实例对象,该对象可以被当做一个路径字符进行处理,同时进行大量的使用功能增强。

绝对路径和相对路径对象

由于windows 和 Linux 描述根路径的方式不同,Windows使用“c:\\” 符号描述此路径为根,而Posix 使用 “ / ”表示根。

  • 绝对路径创建
from pathlib import Path
p = Path("/home/user1/python")
p                      # PosixPath('/home/user1/python')
p.is_absolute()        # True  表示是绝对路径
  • 相对路径创建
p2 = Path("home/user1/")
p2       # home/user1, 此时p2是一个相对路径,绝对路径为当前文件的绝对路径
# 拼接上p2的路径,即 :path(".") / p2
  • 拼接创建
Path("home", "user1", "python")
Path("home") / Path("user1") / "python"
p2 / "python"
# 三种方式都将返回新的PATH对象,都使用了相对路径的拼接home/user1/python
# 绝对路径也可以拼接,但注意根只能在字符串开始,否则将会出现问题 
# 正常拼接
Path("/root", "abc")   # == > PosixPath("/root/abc")
# 拼接过程中遇到新的根,将新的根作为起点继续拼接,之前的路径将会忽略
Path("/root", "/abc") # == > PosixPath("/abc") 
# windows 中遇到拼接根目录,会保留盘符驱动号
>>> PureWindowsPath('c:/Windows', '/Program Files')
PureWindowsPath('c:/Program Files')

 Path对象属性

  • parts        返回分隔符分割后的列表
  • root
  • parents
  • parent
  • name
  • suffix        获取后缀,无返回 " "
  • suffixes    获取后缀们 返回列表,无返回 [ ]
  • stem        基名去除后缀(单个)
# 切割各个部分
p = Path('/usr/bin/python3')
p.parts
# ('/', 'usr', 'bin', 'python3')
p.parts[:3]      # == > /usr/bin
# 获取根
Path('/etc').root
p = Path('/foo/bar/setup.py')
p.parents          # == > 返回一个惰性对象,可正索引,不可超界索引
>>> p.parents[1]
PosixPath('/foo')
>>> p = Path('/a/b/c/basename')
>>> p.parent
PosixPath('/a/b/c')
>>> p.name
'basename'
>>> Path('my/library.tar.gz').suffix
'.gz'
>>> Path('my/library.tar.gar').suffixes
['.tar', '.gar']
>>> Path('my/library.tar.gz').stem
'library.tar'

Path对象方法

  • joinpath(*other)
  • match('b/*.py')
  • is_absolute()
  • with_name(name)
  • with_suffix(suffix)
  • expanduser()
>>> p = Path('~/films/Monty Python')
>>> p.expanduser()
PosixPath('/home/eric/films/Monty Python')
# 换后缀
>>> p = Path('c:/Downloads/pathlib.tar.gz')
>>> p.with_suffix('.bz2')
PosixPath('c:/Downloads/pathlib.tar.bz2')
>>> p.with_name("hello")
PosixPath('c:/Downloads/hello.tar.bz2')

类方法:当前目录和家目录

Path.cwd()
Path.home()

路径的文件类型判断

Path.exists()
Path.is_dir()
Path.is_file()
Path.is_socket()
Path.is_fifo()
Path.is_char_device()
Path.is_block_device()
Path.is_char_device()

路径对应的文件状态信息

Path.stat()       # 软链接显示链接文件信息
Path.lstat()      # 软链接显示被链接对象信息,非软链接不报错正常显示
Path.owner()
Path.group()
Path.lchmod(mode)

路径对应文件及元数据的增删改查

Path.touch(mode=0o666, exist_ok=True)
Path.rename(target)
Path.chmod(mode)
Path.mkdir(mode=0o777, parents=False, exist_ok=False)
Path.rmdir()
Path.replace(target)
Path.unlink()

路径对应文件的读写等文件流操作

path对象可以直接调用相应的方法打开文件,读取内部的内容

Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)
Path.read_bytes()
Path.read_text(encoding=None, errors=None)
Path.write_bytes(data)
Path.write_text(data, encoding=None, errors=None)
Path.iterdir()

遍历目录 

iterdir():不递归的遍历这个目录,返回一个惰性的对象,在os.listdir(dir) 中是返回一个列表

filenum,empty_dir,dir_num = 0, 0, 0
for f in Path(".").iterdir():   # 遍历当前目录
    if f.is_file():
        filenum  += 1
    if f.is_dir():
        for item in f.iterdir():
            if item:
                dir_num += 1
                break 
        else:
            empty_dir += 1

通配符

* 任意字符, 一个任意,[abc]一个指定字符

glob.glob(pattern)    不递归搜索

glob.rglob(pattern)  递归所有目录进行搜素

返回匹配结果的path对象集合的生产器,惰性对象

glob.match(pattern)     匹配成功返回True
# 对当前目录下的.py结尾文件排序,目录不递归
>>> sorted(Path('.').glob('*.py'))
[PosixPath('pathlib.py'), PosixPath('setup.py'), PosixPath('test_pathlib.py')]
# 对该目录下,所有目录下的.py 进行排序
>>> sorted(Path('.').glob('*/*.py'))
[PosixPath('docs/conf.py')]
# 该目录下所有目录中(递归).py文件排序
sorted(Path('.').glob('**/*.py'))
[PosixPath('build/lib/pathlib.py'),
 PosixPath('docs/conf.py'),
 PosixPath('pathlib.py'),
 PosixPath('setup.py'),
 PosixPath('test_pathlib.py')]