优秀的编程知识分享平台

网站首页 > 技术文章 正文

Python文件操作pathlib(Python文件操作与异常处理)

nanyue 2024-08-29 20:54:41 技术文章 4 ℃

pathlib 文件操作模块

阅读需要 15分钟。

  • 之使用 python 操作文件路径,最苦开始使用 os.path。
  • pathlib 库从 python3.4 开始,到 python3.6 已经比较成熟。

为什么会有pathlib模块:规范统一

  1. 老的路径操作函数比较混乱, os, os.path 当中,现在统一可以用 pathlib 管理。
  2. 老的API对于不同操作系统的处理 win,mac 以及 linux 不方便
  3. 老方法使用的是函数,返回的路径通常是个”字符串“,但是字符串还是路径
  4. pathlib 使用简单功能丰富。

pathlib使用 import mathlob 或者 from pathlib import Path

from pathlib import Path

当前目录在哪里

from pathlib import Path
pwd = Path.cwd()
print(pwd)

home目录

from pathlib import Path
pwd = Path.cwd()

print(pwd)
print(Path.home())
C:\Users\admin


home目录在Windows上通常是 c:/User/用户名 这个目录,而Linux通常也是用户的主目录

下面是一个linux服务器上root用户的home目录 /root


Paht的各种用法

  • 根据字符串构建目录: Path(r"C:\Users\philipp\realpython\file.txt")
p =Path(r"C:\Users\philipp\realpython\file.txt")
print(p,)
print(p.parent) # 获取上级目录
C:\Users\philipp\realpython\file.txt
C:\Users\philipp\realpython

Path对象的parent方法可以找到它的上层目录,一直可以找到最上层的根目录

  • 获取当前执行的Python文件的完整路径和目录
print(Path(__file__))
print(Path(__file__).parent)
  • 移动文件:比如将某个目录下的 txt文本文件移到到其他目录
for file_path in Path.cwd().glob("*.txt"):
    # new_path = Path("archive",file_path.name)    
    new_path = Path("archive") / file_path.name
    #以上两种方式都是构建新目录文件 的路径,效果是一样的
    print(new_path)
    file_path.rename(new_path)
  • 组合文件路径 joinpath
a  = Path.home().joinpath("python", "scripts", "test.py")
print(a)


Paht对象的关键组件

  • .name: 文件名,没有目录路径 a.txt
  • .stem: 没有扩展名的文件名 a
  • .suffix: 文件后缀
  • .anchor: 文件作者
  • .parent: 父目录
>>> from pathlib import Path
>>> path = Path(r"C:\Users\gahjelle\realpython\test.md")
>>> path
WindowsPath('C:/Users/gahjelle/realpython/test.md')

>>> path.name
'test.md'

>>> path.stem
'test'

>>> path.suffix
'.md'

>>> path.anchor
'C:\\'

>>> path.parent
WindowsPath('C:/Users/gahjelle/realpython")

>>> path.parent.parent
WindowsPath('C:/Users/gahjelle')

使用 / 斜杠 连接目录如下

path.parent.parent / f"new{path.suffix}"
PosixPath('/home/gahjelle/new.md')

读取文件

假设有一个文件 的内容如下

<!-- shopping_list.md -->

# Shopping List

## Fruit

* Banana
* Apple
* Peach

## Candy

* Chocolate
* Nougat Bits



# read_shopping_list.py

from pathlib import Path

path = Path.cwd() / "shopping_list.md"
with path.open(mode="r", encoding="utf-8") as md_file:
    content = md_file.read()
    groceries = [line for line in content.splitlines() if line.startswith("*")]
print("\n".join(groceries))
  • .read_text() 字符串方式读取文件
  • .read_bytes() 二进制方式读取文件
  • .write_text() 写入文本到 文件
  • .write_bytes() 写入二进制数据到 文件
from pathlib import Path

path = Path.cwd() / "shopping_list.md"
content = path.read_text(encoding="utf-8")
groceries = [line for line in content.splitlines() if line.startswith("*")]
print("\n".join(groceries))

#写文件
Path("plain_list.md").write_text("\n".join(groceries), encoding="utf-8")

重命名文件

>>> from pathlib import Path
>>> txt_path = Path("/home/gahjelle/realpython/hello.txt")
>>> txt_path
PosixPath("/home/gahjelle/realpython/hello.txt")

>>> md_path = txt_path.with_suffix(".md")
PosixPath('/home/gahjelle/realpython/hello.md')

>>> txt_path.replace(md_path)

with_suffix 构建一个新的Paht 把 .txt 后缀修改为 .md

使用 replace函数把电脑上的文件名重新命名

复制文件:其中一种办法 内容复制创建新文件

>>> source = Path("shopping_list.md")
>>> destination = source.with_stem("shopping_list_02")
>>> destination.write_bytes(source.read_bytes())

创建新文件 touch 函数

>>> from pathlib import Path
>>> filename = Path("hello.txt")
>>> filename.exists()
False

>>> filename.touch()
>>> filename.exists()
True

>>> filename.touch()

如果文件已经存在,调用touch函数时exist_ok为False则会报错。

>>> filename.touch(exist_ok=False)
Traceback (most recent call last):
  ...
FileExistsError: [Errno 17] File exists: 'hello.txt'

Pathlib应用小例子

统计不同文件类型的数量

>>> from pathlib import Path
>>> from collections import Counter
>>> Counter(path.suffix for path in Path.cwd().iterdir())
Counter({'.md': 2, '.txt': 4, '.pdf': 2, '.py': 1})
>>> from collections import Counter
>>> Counter(path.suffix for path in Path.cwd().iterdir())
Counter({'': 8, '.dll': 4, '.txt': 2, '.exe': 2})
>>> 

显示目录的树形结构

def tree(directory):
    print(f"+ {directory}")
    for path in sorted(directory.rglob("*")):
        depth = len(path.relative_to(directory).parts)
        spacer = "    " * depth
        print(f"{spacer}+ {path.name}")



查找最近修改的文件

>> from pathlib import Path
>>> from datetime import datetime
>>> directory = Path.cwd()
>>> time, file_path = max((f.stat().st_mtime, f) for f in directory.iterdir())
>>> print(datetime.fromtimestamp(time), file_path)
2022-04-03 09:30:57.448853 C:\Users\admin\AppData\Local\Programs\Python\Python38\Scripts
>>> 

创建唯一的文件名,不重名

def unique_path(directory, name_pattern):
    counter = 0
    while True:
        counter += 1
        path = directory / name_pattern.format(counter)
        if not path.exists():
            return path

代码很简单实际上就是有一个计数器 counter作为文件名中的一部分如果存在同名的文件,counter 加1 直到没有重复的名字。

Tags:

最近发表
标签列表