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 相关文章推荐
python抓取最新博客内容并生成Rss
May 17 Python
PyCharm代码格式调整方法
May 23 Python
pip安装时ReadTimeoutError的解决方法
Jun 12 Python
pyqt5的QComboBox 使用模板的具体方法
Sep 06 Python
Python爬虫之正则表达式的使用教程详解
Oct 25 Python
Python字典遍历操作实例小结
Mar 05 Python
使用python制作游戏下载进度条的代码(程序说明见注释)
Oct 24 Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
Mar 20 Python
python3.9实现pyinstaller打包python文件成exe
Dec 13 Python
Pycharm创建python文件自动添加日期作者等信息(步骤详解)
Feb 03 Python
Python中else的三种使用场景
Jun 16 Python
教你如何使用Python开发一个钉钉群应答机器人
Jun 21 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的类树(支持无限分类)
2006/10/09 PHP
php读取mysql的简单实例
2014/01/15 PHP
php恢复数组的key为数字序列的方法
2015/04/28 PHP
CI分页类首页、尾页不显示的解决方法
2016/03/28 PHP
php+html5+ajax实现上传图片的方法
2016/05/14 PHP
PHP命名空间namespace的定义方法详解
2017/03/29 PHP
基于jquery1.4.2的仿flash超炫焦点图播放效果
2010/04/20 Javascript
js操作textarea方法集合封装(兼容IE,firefox)
2011/02/22 Javascript
SharePoint 客户端对象模型 (一) ECMA Script
2011/05/22 Javascript
js获取浏览器的可视区域尺寸的实现代码
2011/11/30 Javascript
jQuery实现长文字部分显示代码
2013/05/13 Javascript
鼠标移入移出事件改变图片的分辨率的两种方法
2013/12/17 Javascript
javascript制作游戏开发碰撞检测的封装代码
2015/03/31 Javascript
JavaScript学习笔记之取数组中最大值和最小值
2016/03/23 Javascript
vue组件间通信解析
2017/03/01 Javascript
微信小程序实战之上拉(分页加载)效果(2)
2017/04/17 Javascript
EasyUI创建人员树的实例代码
2017/09/15 Javascript
微信小程序 搜索框组件代码实例
2019/09/06 Javascript
JavaScript RegExp 对象用法详解
2019/09/24 Javascript
Layui数据表格判断编辑输入的值,是否为我需要的类型详解
2019/10/26 Javascript
推荐几个不错的console调试技巧实现
2019/12/20 Javascript
Python虚拟环境virtualenv的安装与使用详解
2017/05/28 Python
Python基于list的append和pop方法实现堆栈与队列功能示例
2017/07/24 Python
python实现图像检索的三种(直方图/OpenCV/哈希法)
2019/08/08 Python
tensorflow转换ckpt为savermodel模型的实现
2020/05/25 Python
HTML5 canvas基本绘图之绘制矩形
2016/06/27 HTML / CSS
武汉世纪畅想数字传播有限公司.NET笔试题
2014/07/22 面试题
实习自荐信
2013/10/13 职场文书
仪器仪表检测毕业生自荐信
2013/10/31 职场文书
党支部党的群众路线对照检查材料
2014/09/24 职场文书
主持人开幕词
2015/01/29 职场文书
接待员岗位职责
2015/02/13 职场文书
Vue CLI中模式与环境变量的深入详解
2021/05/30 Vue.js
python使用pymysql模块操作MySQL
2021/06/16 Python
JS精髓原型链继承及构造函数继承问题纠正
2022/06/16 Javascript
Python 避免字典和元组的多重嵌套问题
2022/07/15 Python