Python中的pathlib.Path为什么不继承str详解


Posted in Python onJune 23, 2019

起步

既然所有路径都可以表示为字符串,为什么 pathlib.Path 不继承 str ? 这个想法的提出在 https://mail.python.org/pipermail//python-ideas/2016-April/039475.html 可以看到,其中,还提出了将 p'/some/path/to/a/file' 返回 path.Path 实例的想法。

路径都是字符串吗?

从面向对象的继承的思想来看,如果 Path 继承自 str ,那么所有的路径都应该是字符串。但所有的路径都是字符串吗?答案是不。在 POSIX 的接口中,允许二进制字符串作为路径。也就是说路径还有二进制路径的形式存在。所以并不是所有路径都是字符串,尽管所有路径确实都能用字符串表示。

文件系统路径协议
基于上述原因,Python 提出了文件系统路径协议的提案 PEP-519 ,该协议提供str 或 bytes 来表示的文件系统路径。这个协议也就诞生了处理路径的 pathlib 模块 PEP-428,该模块遵守了路径协议并将路径视为对象。

协议的实现一般也是通过鸭子协议来满足,这点出发 Path 也没必要继承 str 。

不是字符串的Path使用上有什么影响

在 Python3.5 及以下将不能用 Path 作为open的参数:

import pathlib
p = pathlib.Path('a.txt')
content = open(p, 'r').read() # 换成 open(str(p), 'r') 可以运行

将会报错:

TypeError: invalid file: PosixPath('a.txt')

但这点在 Python3.6 得到的改善: https://docs.python.org/3/whatsnew/3.6.html#pep-519-adding-a-file-system-path-protocol

内置 open() 函数已更新为接受 os.PathLike 对象,os 和 os.path 模块中的所有相关函数以及大多数其他函数和类标准库都使用了文件路径系统协议。

>>> import pathlib
>>> with open(pathlib.Path("README")) as f:
...   contents = f.read()
...
>>> import os.path
>>> os.path.splitext(pathlib.Path("some_file.txt"))
('some_file', '.txt')
>>> os.path.join("/a/b", pathlib.Path("c"))
'/a/b/c'
>>> import os
>>> os.fspath(pathlib.Path("some_file.txt"))
'some_file.txt'

对于低版本的可以使用兼容性更好的:

with p.open('r') as f:
  content = f.read()

如果路径继承str会怎样

或者说如果我自己创建个路径类继承自 str ,这当然可以,也没人组织你,但我想从设计上阐述下这个做法的弊端。

一方面,这个做法会让路径隐式地视为字符串。不满足Python之禅的 显式胜于隐式 的理念。

另一方面也是比较重要的一点,这个做法淡化了 str 和 bytes 的界限,想想Python 2中二进制文本数据和文本数据的隐式兼容性导致了一个令人头疼的问题,将在这里又重新埋下隐患。这是倒退式的做法。

总结

对于路径类为什么不继承字符串,本文从路径的形式,路径协议,以及API设计解释了。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

扩展阅读

  • Python-ideas: Making pathlib paths inherit from str
  • PEP 519 -- Adding a file system path protocol
  • PEP 428 -- The pathlib module -- object-oriented filesystem paths
  • What's New In Python 3.6 pep-519-adding-a-file-system-path-protocol
Python 相关文章推荐
在Django的模型中执行原始SQL查询的方法
Jul 21 Python
python文件的md5加密方法
Apr 06 Python
python+selenium打印当前页面的titl和url方法
Jun 22 Python
python实现石头剪刀布程序
Jan 20 Python
python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)
Jun 27 Python
python如何实现不用装饰器实现登陆器小程序
Dec 14 Python
Python自动重新加载模块详解(autoreload module)
Apr 01 Python
Python如何脚本过滤文件中的注释
May 27 Python
python为什么会环境变量设置不成功
Jun 23 Python
利用python+ffmpeg合并B站视频及格式转换的实例代码
Nov 24 Python
写一个Python脚本自动爬取Bilibili小视频
Apr 24 Python
如何解决.cuda()加载用时很长的问题
May 24 Python
Python中判断子串存在的性能比较及分析总结
Jun 23 #Python
树莓派与PC端在局域网内运用python实现即时通讯
Jun 22 #Python
树莓派采用socket方式文件传输(python)
Jun 22 #Python
树莓派用python中的OpenCV输出USB摄像头画面
Jun 22 #Python
树莓派使用USB摄像头和motion实现监控
Jun 22 #Python
树莓派动作捕捉抓拍存储图像脚本
Jun 22 #Python
python+openCV利用摄像头实现人员活动检测
Jun 22 #Python
You might like
PHP内置函数生成随机数实例
2019/01/18 PHP
详解PHP PDO简单教程
2019/05/28 PHP
在JavaScript中获取请求的URL参数[正则]
2010/12/25 Javascript
跨域请求之jQuery的ajax jsonp的使用解惑
2011/10/09 Javascript
JS异常处理的一个想法(sofish)
2013/03/14 Javascript
自己写的Javascript计算时间差函数
2013/10/28 Javascript
js判断登录与否并确定跳转页面的方法
2015/01/30 Javascript
简单对比分析JavaScript中的apply,call与this的使用
2015/12/04 Javascript
jQuery实现点击弹出背景变暗遮罩效果实例代码
2016/06/24 Javascript
微信小程序 教程之wxapp 视图容器 view
2016/10/19 Javascript
Canvas 制作动态进度加载水球详解及实例代码
2016/12/09 Javascript
Vue 实现列表动态添加和删除的两种方法小结
2018/09/07 Javascript
vue-vuex中使用commit提交mutation来修改state的方法详解
2018/09/16 Javascript
js防抖和节流的深入讲解
2018/12/06 Javascript
angular 服务随记小结
2019/05/06 Javascript
vue单应用在ios系统中实现微信分享功能操作
2020/09/07 Javascript
[01:14]2014DOTA2展望TI 剑指西雅图newbee战队专访
2014/06/30 DOTA
Python内置函数的用法实例教程
2014/09/08 Python
python简单分割文件的方法
2015/07/30 Python
通过python的matplotlib包将Tensorflow数据进行可视化的方法
2019/01/09 Python
Django的models中on_delete参数详解
2019/07/16 Python
使用Python来做一个屏幕录制工具的操作代码
2020/01/18 Python
pytorch实现Tensor变量之间的转换
2020/02/17 Python
python实现word文档批量转成自定义格式的excel文档的思路及实例代码
2020/02/21 Python
基于python爬取链家二手房信息代码示例
2020/10/21 Python
python openCV自制绘画板
2020/10/27 Python
Python request post上传文件常见要点
2020/11/20 Python
使用Python爬取Json数据的示例代码
2020/12/07 Python
Html5 页面适配iPhoneX(就是那么简单)
2019/09/05 HTML / CSS
毕业生见习报告总结
2014/11/08 职场文书
幼儿教师辞职信范文
2015/03/02 职场文书
任命书怎么写
2015/03/02 职场文书
CSS Transition通过改变Height实现展开收起元素
2021/08/07 HTML / CSS
Redis Stream类型的使用详解
2021/11/11 Redis
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
2022/05/30 NodeJs
利用Apache Common将java对象池化的问题
2022/06/16 Servers