Python中的pathlib.Path为什么不继承str详解
起步
既然所有路径都可以表示为字符串,为什么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的参数:
importpathlib p=pathlib.Path('a.txt') content=open(p,'r').read()#换成open(str(p),'r')可以运行
将会报错:
TypeError:invalidfile: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模块中的所有相关函数以及大多数其他函数和类标准库都使用了文件路径系统协议。
>>>importpathlib >>>withopen(pathlib.Path("README"))asf: ...contents=f.read() ... >>>importos.path >>>os.path.splitext(pathlib.Path("some_file.txt")) ('some_file','.txt') >>>os.path.join("/a/b",pathlib.Path("c")) '/a/b/c' >>>importos >>>os.fspath(pathlib.Path("some_file.txt")) 'some_file.txt'
对于低版本的可以使用兼容性更好的:
withp.open('r')asf: content=f.read()
如果路径继承str会怎样
或者说如果我自己创建个路径类继承自str,这当然可以,也没人组织你,但我想从设计上阐述下这个做法的弊端。
一方面,这个做法会让路径隐式地视为字符串。不满足Python之禅的显式胜于隐式的理念。
另一方面也是比较重要的一点,这个做法淡化了str和bytes的界限,想想Python2中二进制文本数据和文本数据的隐式兼容性导致了一个令人头疼的问题,将在这里又重新埋下隐患。这是倒退式的做法。
总结
对于路径类为什么不继承字符串,本文从路径的形式,路径协议,以及API设计解释了。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。
扩展阅读
- Python-ideas:Makingpathlibpathsinheritfromstr
- PEP519--Addingafilesystempathprotocol
- PEP428--Thepathlibmodule--object-orientedfilesystempaths
- What'sNewInPython3.6pep-519-adding-a-file-system-path-protocol