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 multiprocessing模块中的Pipe管道使用实例
Apr 11 Python
C#返回当前系统所有可用驱动器符号的方法
Apr 18 Python
自动化Nginx服务器的反向代理的配置方法
Jun 28 Python
python中matplotlib实现最小二乘法拟合的过程详解
Jul 11 Python
python获取外网IP并发邮件的实现方法
Oct 01 Python
Python之ReportLab绘制条形码和二维码的实例
Jan 15 Python
django 多数据库配置教程
May 30 Python
python实现登录密码重置简易操作代码
Aug 14 Python
PyTorch如何搭建一个简单的网络
Aug 24 Python
Python logging日志库空间不足问题解决
Sep 14 Python
python中spy++的使用超详细教程
Jan 29 Python
利用Python脚本写端口扫描器socket,python-nmap
Jul 23 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单例模式示例分享
2015/02/12 PHP
十个PHP高级应用技巧果断收藏
2015/09/25 PHP
使用一个for循环将N*N的二维数组的所有值置1实现方法
2017/05/29 PHP
用JavaScript仿PS里的羽化效果代码
2011/12/20 Javascript
关于使用 jBox 对话框的提交不能弹出问题解决方法
2012/11/07 Javascript
js实现点击图片改变页面背景图的方法
2015/02/28 Javascript
jQuery+css3实现Ajax点击后动态删除功能的方法
2015/08/10 Javascript
HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
2015/11/25 Javascript
基于Jquery实现焦点图淡出淡入效果
2015/11/30 Javascript
input点击后placeholder中的提示消息消失
2016/01/15 Javascript
实例讲解JavaScript中instanceof运算符的用法
2016/06/08 Javascript
jQuery模拟窗口抖动效果
2017/03/15 Javascript
Bootstrap标签页(Tab)插件切换echarts不显示问题的解决
2018/07/13 Javascript
实现一个 Vue 吸顶锚点组件方法
2019/07/10 Javascript
Vue实现简易计算器
2020/02/25 Javascript
在Vue里如何把网页的数据导出到Excel的方法
2020/09/30 Javascript
js实现Element中input组件的部分功能并封装成组件(实例代码)
2021/03/02 Javascript
python实现八大排序算法(2)
2017/09/14 Python
简单谈谈python基本数据类型
2018/09/26 Python
python super的使用方法及实例详解
2019/09/25 Python
Python qrcode 生成一个二维码的实例详解
2020/02/12 Python
python 中的paramiko模块简介及安装过程
2020/02/29 Python
浅谈HTML5新增及移除的元素
2016/06/27 HTML / CSS
美国Rue La La闪购网站:奢侈品、中高档品牌限时折扣
2016/10/19 全球购物
英国家庭、花园、汽车和移动解决方案:Easylife Group
2018/05/23 全球购物
Tostadora意大利:定制T恤
2019/04/08 全球购物
保加利亚服装和鞋类购物网站:Bibloo.bg
2020/11/08 全球购物
网页设计个人找工作求职信
2013/11/28 职场文书
股份转让协议书范本
2015/01/27 职场文书
部队2015年终工作总结
2015/04/02 职场文书
奔腾年代观后感
2015/06/09 职场文书
小学体育课教学反思
2016/02/16 职场文书
村党总支部公开承诺书2016
2016/03/25 职场文书
学校2016年全国助残日活动总结
2016/04/01 职场文书
进阶篇之linux环境下安装MySQL数据库
2022/04/09 MySQL
TS 类型收窄教程示例详解
2022/09/23 Javascript