Pathlib使用简单教程

pathlib – 面向对像的文件系统路径

从python3.4以后,pathlib内置,最初只是以为pathlib只是os.path功能的一个面像对像话,但在2019年,Django框架将os.path用pathlib换了。以下将简单说明。

1、python常规路径处理中的问题

在python常规的路径处理中,仅把路径当做字符串路径,到目前为止,尽管有点麻烦,但使用路径作为os.path模块的字符串已经足够了。但是,路径实际上并不是字符串,因此必须使用多个模块来提供分散在整个标准库中的不同功能,包括os,glob和shutil等库。以下代码仅使用三个模块将多个python文件从当前目录复制到另一个名为src的目录。

import os
import shutil
import glob

fnames = glob.glob("*.py")
for fname in fnames:
    new_path = os.path.join("src",fname)
    shutil.copy(fname,new_path)

以上操作比较复杂,用到多个模块,下面将逐步介绍pathlib来实现这个功能

2、填加并创建新的路径

当你想要实现以下功能:

  • 当前路径下有一个file.txt,相要创建一个file_another.txt的文件
  • 想将file_another.txt的绝对路径保存到一个变量中

看一下如何使用os来实现

from os.path import abspath,join,dirname

file_path=abspath("file.txt")
base_dir = dirname(file_path)
file_another_path = join(base_dir,"file_another.txt")

print(file_path)
print(base_dir)
print(file_another_path)

/home/tl/test/file.txt
/home/tl/test
/home/tl/test/file_another.txt

相同的功能用pathlib来实现

from pathlib import Path

file_path = Path('file.txt').resolve()
base_dir = file_path.parent
file_another_path=base_dir / "file_another.txt"

print(file_path)
print(base_dir)
print(file_another_path)

/home/tl/test/file.txt
/home/tl/test
/home/tl/test/file_another.txt

3、创建文件夹和文件重命名

有两个演示:

  • 在src/stuff己经创建的情况下,尝试创建
  • 将src下文件.config重命名成.stuffconfig
os.makedirs(os.path.join("src","stuff"),exist_ok=True)
os.rename("src/.config","src/.stuffconfig")

使用pathlib来做相同的事

from pathlib import Path 

Path("src/stuff").mkdir(parents=True,exist_ok=True)
Path("src/.config").rename("src/.stuffconfig")

4、列举文件夹下特定文件类型

递归列举文件下所有指定类型的文件,比如所有.py文件


src/
├── stuff
│   ├── __init__.py
│   └── submodule.py
├── .stuffconfig
├── b.py
└── module.py

#通常是使用glob第三方包来解决这个问题
import glob

top_level_py_files = glob.glob("src/*.py")
all_py_files = glob.glob("src/**/*.py",recursive=True)
print(top_level_py_files)
print(all_py_files)

['src/module.py', 'src/b.py']
['src/module.py', 'src/b.py', 'src/stuff/__init__.py', 'src/stuff/submodule.py']

以上方法可以很好的解决问题,但需要调用第三方包,如果只是用一个包, 那么pathlib包含globrglob功能,可以实现相同功能

from pathlib import Path

top_level_py_files =Path("src").glob("*.py")
all_py_files = Path("src").rglob("*.py")
print(list(top_level_py_files))#返回的是生成器,所以要加list
print(list(all_py_files))

[PosixPath('src/module.py'), PosixPath('src/b.py')]
[PosixPath('src/module.py'), PosixPath('src/b.py'), PosixPath('src/stuff/__init__.py'), PosixPath('src/stuff/submodule.py')]

5、打开多个文件并读取内容

import glob 

contents=[]
for fname in glob.glob("src/**/*.py",recursive=True):
    with open(fname,'r') as f:
        contents.append(f.read())
print(contents)

['this is module.py', 'this is b.py\n', 'this is stuff/__init__.py', 'this is stuff/submodule.py']

pathlib可以实现几乎一样的功能

from pathlib import Path

contents=[]

for fname in Path("src").rglob("*.py"):
    with open(fname,'r') as f:
        contents.append(f.read())
print(contents)

['this is module.py', 'this is b.py\n', 'this is stuff/__init__.py', 'this is stuff/submodule.py']

5、pathlib模块分析

pathlib中有几个不同的类,主要是针对不同的操作系统,这里主要讲Path这个类

5.1 运算符

在产生子目录时,可以使用/来代替os.path.join

from pathlib import Path 
base_dir = Path("src")
child_path = base_dir / "stuff"
file_path = child_path / "__init__.py"
print(file_path)

src/stuff/__init__.py

5.2 属性和方法

下表,列出了Path的一些属性和方法

Path
│
├── Attributes
│       ├── parts
│       ├── parent & parents
│       ├── name
│       ├── suffix & suffixes
│       └── stem
│
│
└── Methods
        ├── joinpath(*other)
        ├── cwd()
        ├── home()
        ├── exists()
        ├── expanduser()
        ├── glob()
        ├── rglob(pattern)
        ├── is_dir()
        ├── is_file()
        ├── is_absolute()
        ├── iterdir()
        ├── mkdir(mode=0o777, parents=False, exist_ok=False)
        ├── open(mode='r', buffering=-1, encoding=None, errors=None, newline=None)
        ├── rename(target)
        ├── replace(target)
        ├── resolve(strict=False)
        └── rmdir()

我们将逐一使用以上内容的进行说明,使用的例子如下:

src/
├── stuff
│   ├── __init__.py
│   └── submodule.py
├── .stuffconfig
├── somefile.tar.gz
└── module.py
5.2.1 Path.parts

会将整个路径的各个部分,以元组的形式的返回

from pathlib import Path
file_path = Path("src/stuff/__init__.py")
print(file_path.parts)

('src', 'stuff', '__init__.py')
5.2.2 Path.parents & Path.parent

Path.parents返回一个不可变的逐次父路径;而Path.parent则返回当前路径的父路径

file_path = Path("src/stuff/__init__.py")

for parent in file_path.parents:
    print(parent)


src/stuff
src
.
file_path.parent

PosixPath('src/stuff')
5.2.3 Path.name

返回路径的最后一部分,适合获得最后名字

file_path = Path("src/module.py")
file_path.name

'module.py'
5.2.3 Path.suffixes & Path.suffix

Path.suffixes将会返回所有的后缀,Path.suffix只返回最后的一个后缀

file_path = Path("src/somefile.tar.gz")
print(file_path.suffixes)
print(file_path.suffix)

['.tar', '.gz']
.gz
5.2.4 Path.stem

将返回文件名中除后缀以外的部分

file_path = Path("src/somefile.tar.gz")
print(file_path.stem)

somefile.tar
5.2.5 Path.joinpath

可以将多个路径拼接起来,代替使用/

file_path = Path("src").joinpath("stuff").joinpath("__init__.py")
print(file_path)
file_path = Path("src") / "stuff" / "__init__.py"
print(file_path)

src/stuff/__init__.py
src/stuff/__init__.py
5.2.6 Path.cwd()

类似os.getcwd(),返回当前路径

print(Path.cwd())
print(os.getcwd())

/home/tl/test
/home/tl/test
5.2.7 Path.home()

返回home路径

print(Path.home())

/home/tl
5.2.8 Path.exists()

判断文件或文件夹是否存在,返回boolean数据

print(Path("src/stuff/thisisabsent.py").exists())
print(Path("src/stuff/__init__.py").exists())

False
True
5.2.9 Path.expanduser()

~置换成返回带有路径的新路径

print(Path("~/test/usr/stuff/__init__.py").expanduser())

/home/tl/test/usr/stuff/__init__.py
5.2.10 Path.glob()

返回所有符合正则表达的内容,返回的是生成器

#获取所有src/stuff文件夹下,以.py为后缀的文件

for fname in Path("src/stuff").glob("*.py"):
    print(fname)

src/stuff/__init__.py
src/stuff/submodule.py
5.2.11 Path.rglob()

以递归的方式,返回所有符合要求的文件路径

# 比如要返回所有src文件夹下以.py为后缀的文件
for fname in Path("src").rglob("*.py"):
    print(fname)

src/module.py
src/b.py
src/stuff/__init__.py
src/stuff/submodule.py
5.2.12 Path.is_dir()

返回路径是否为路径,返回类型为 boolean

print(Path("src/stuff").is_dir())
print(Path("src/stuff/__init__.py").is_dir())

True
False
5.2.13 Path.is_file()

返回路径是否为文件,返回类型为 boolean

print(Path("src/stuff").is_file())
print(Path("src/stuff/__init__.py").is_file())

False
True
5.2.14 Path.is_absolute()

返回路径是否为绝对路径,如果是相以路径,则返返False

print(Path("src/stuff/__init__.py").is_absolute())
print(Path("/home/tl/test/src/stuff/__init__.py").is_absolute())

False
True
5.2.15 Path.iterdir()

如果路径点指向文件夹,将返回当前文件夹下的所有文件和文件夹的路径

for content in Path('src').iterdir():
    print(content)

src/.stuffconfig
src/somefile.tar.gz
src/module.py
src/b.py
src/stuff
5.2.16 Path.mkdir(mode=0o777, parents=False, exist_ok=False)

在给定路径下创建新路径。

  • mode:文件的权限控制
  • parentes:如是是True,那么缺失的路径中的内容都会自动创建,否则会报FileNotFoundError的错
  • exist_ok:如果是False,那么当路径已经存在时,会报错;当是True时,会忽略报错
Path("src/other/side").mkdir(parents=True)

5.2.17 Path.open(mode=’r’, buffering=-1, encoding=None, errors=None, newline=None)

和内建函数open一样

with Path("src/module.py").open('r') as f:
    content = f.read()
    print(content)

this is module.py
5.2.18 Path.rename(target)

对文件或文件夹重名命,并指向新的文件。如果要重命名的文件不存在,那么就会报错。

Path("src/stuff/submodule.py").rename("src/stuff/anothermodule.py")

5.2.18 Path.replace(target)

和rename有些相似,以target代替原文件

file_path = Path("src/stuff/anothermodule.py")
file_path.replace(file_path.parent / "Dockerfile")

5.2.19 Path.resolve(strict=False)

返回绝对路径,如果strick是True,并且文件不存在则会报错

Path("src/stuff/Dockerfile").resolve()

PosixPath('/home/tl/test/src/stuff/Dockerfile')
5.2.20 Path.rmdir

删除路径,一定要保证文件夹是空的,否则报错,相当于os.rmdir

参考资料

https://docs.python.org/3/library/pathlib.html

  • 4
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值