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使用gensim计算文档相似性
Apr 10 Python
python3实现暴力穷举博客园密码
Jun 19 Python
Python3.6简单操作Mysql数据库
Sep 12 Python
python里使用正则的findall函数的实例详解
Oct 19 Python
解决python使用open打开文件中文乱码的问题
Dec 29 Python
Python面向对象程序设计之继承与多继承用法分析
Jul 13 Python
利用python实现对web服务器的目录探测的方法
Feb 26 Python
Python音频操作工具PyAudio上手教程详解
Jun 26 Python
django页面跳转问题及注意事项
Jul 18 Python
python同步windows和linux文件
Aug 29 Python
PyQt5的相对布局管理的实现
Aug 07 Python
Python+unittest+DDT实现数据驱动测试
Nov 30 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 注册时输入信息验证器的实现详解
2013/07/05 PHP
PHP 二维数组根据某个字段排序的具体实现
2014/06/03 PHP
php过滤表单提交的html等危险代码
2014/11/03 PHP
PHP响应post请求上传文件的方法
2015/12/17 PHP
浅析PHP中的闭包和匿名函数
2017/12/25 PHP
js escape,unescape解决中文乱码问题的方法
2010/05/26 Javascript
JavaScript高级程序设计 客户端存储学习笔记
2011/09/10 Javascript
JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(六)
2012/04/07 Javascript
JS实现完全语义化的网页选项卡效果代码
2015/09/15 Javascript
深入探究AngularJS框架中Scope对象的超级教程
2016/01/04 Javascript
javascript 单例模式详解及简单实例
2017/02/14 Javascript
Jquery-data的三种用法
2017/04/18 jQuery
vue与bootstrap实现时间选择器的示例代码
2017/08/26 Javascript
iview table render集成switch开关的实例
2018/03/14 Javascript
关于微信公众号开发无法支付的问题解决
2018/12/28 Javascript
微信小程序后台持续定位功能使用详解
2019/08/23 Javascript
js原生map实现的方法总结
2020/01/19 Javascript
JavaScript设计模式之门面模式原理与实现方法分析
2020/03/09 Javascript
详解vue3.0 的 Composition API 的一种使用方法
2020/10/26 Javascript
[51:15]完美世界DOTA2联赛PWL S2 PXG vs Magma 第一场 11.21
2020/11/24 DOTA
python检测远程端口是否打开的方法
2015/03/14 Python
python使用WMI检测windows系统信息、硬盘信息、网卡信息的方法
2015/05/15 Python
Python中join函数简单代码示例
2018/01/09 Python
Python 安装 virturalenv 虚拟环境的教程详解
2020/02/21 Python
Django框架models使用group by详解
2020/03/11 Python
Python调用shell命令常用方法(4种)
2020/05/11 Python
如何基于Python按行合并两个txt
2020/11/03 Python
意大利消费电子产品购物网站:SLG Store
2019/12/26 全球购物
Miller Harris官网:英国小众香水品牌
2020/09/24 全球购物
上海奥佳笔试题面试题
2016/11/16 面试题
2014年法制宣传日活动方案
2014/11/02 职场文书
校长师德表现自我评价
2015/03/04 职场文书
2016秋季校长开学典礼致辞
2015/11/26 职场文书
Django与数据库交互的实现
2021/06/03 Python
Java Socket实现多人聊天系统
2021/07/15 Java/Android
Python 装饰器(decorator)常用的创建方式及解析
2022/04/24 Python