当前位置: 首页 > 科技观察

请不要使用Os.Path

时间:2023-03-22 14:24:49 科技观察

前段时间,在使用新版Django时,发现settings.py中的第一行代码由importosBASE_DIR=os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))变成frompathlibimportPathBASE_DIR=Path(__file__).resolve().parent.parent所以我很好奇,os和pathlib也是标准库,为什么pathlib得到受到Django的青睐?研究了pathlib之后,发现这是一个非常高效便捷的工具。最适合用它来处理文件系统路径相关的操作。它集成了许多快速功能并提高了您的编程效率。然后就好了。接下来我们就来看看为什么pathlib更值得我们使用。Pathlibvsos就不多说了,先看用法对比:比如打印当前路径:useos:In[13]:importosIn[14]:os.getcwd()Out[14]:'/Users/aaron'使用pathlib:In[15]:frompathlibimportPathIn[16]:Path.cwd()Out[16]:PosixPath('/Users/aaron')In[17]:print(Path.cwd())/Users/aaron与print的结果相同,但os.getcwd()返回一个字符串,而Path.cwd()返回一个PosixPath类。也可以在这条路径上进行后续操作,会很方便。判断路径是否存在:useos:In[18]:os.path.exists("/Users/aaron/tmp")Out[18]:Trueusepathlib:In[21]:tmp=Path("/Users/aaron/tmp")In[22]:tmp.exists()Out[22]:True可见pathlib的可读性更强,更面向对象。显示文件夹内容In[38]:os.listdir("/Users/aaron/tmp")Out[38]:['.DS_Store','.hypothesis','b.txt','a.txt','c.py','.ipynb_checkpoints']In[39]:tmp.iterdir()Out[39]:In[40]:list(tmp.iterdir())Out[40]:[PosixPath('/Users/aaron/tmp/.DS_Store'),PosixPath('/Users/aaron/tmp/.hypothesis'),PosixPath('/Users/aaron/tmp/b.txt'),PosixPath('/Users/aaron/tmp/a.txt'),PosixPath('/Users/aaron/tmp/c.py'),PosixPath('/Users/aaron/tmp/.ipynb_checkpoints')]可以看到Path().iterdir返回一个生成器,在目录文件很多的情况下可以大大节省内存,提高效率。通配符支持os不支持包含通配符的路径,但是pathlib可以:In[45]:list(Path("/Users/aaron/tmp").glob("*.txt"))Out[45]:[PosixPath('/Users/aaron/tmp/b.txt'),PosixPath('/Users/aaron/tmp/a.txt')]方便读写文件操作这是pathlib独有的:f=Path('test_dir/test.txt'))f.write_text('Thisisasentence.')f.read_text()也可以使用with语句:>>>p=Path('setup.py')>>>withp.open()asf:f.readline()...'#!/usr/bin/envpython3\n'获取文件的元数据In[56]:p=Path("/Users/aaron/tmp/c.py")In[57]:p.stat()Out[57]:os.stat_result(st_mode=33188,st_ino=35768389,st_dev=16777221,st_nlink=1,st_uid=501,st_gid=20,st_size=20,st_atime=1620633580,st_mtime=1620633578,st_ctime=1620633578)In[58]:p.partsOut[58]:('/','Users','aaron','tmp','c.py')In[59]:p.parentOut[59]:PosixPath('/Users/aaron/tmp')In[60]:p.resolve()Out[60]:PosixPath('/Users/aaron/tmp/c.py')In[61]:p.存在()Out[61]:TrueIn[62]:p.is_dir()Out[62]:FalseIn[63]:p.is_file()Out[63]:TrueIn[64]:p.owner()Out[64]]:'aaron'In[65]:p.group()Out[65]:'staff'In[66]:p.nameOut[66]:'c.py'In[67]:p.suffixOut[67]:'.py'In[68]:p.suffixesOut[68]:['.py']In[69]:p.stemOut[69]:与os.path.join相比,'c'路径的connectionjoin使用/?>>>p=PurePosixPath('foo')>>>p/'bar'PurePosixPath('foo/bar')>>>p/PurePosixPath('bar')PurePosixPath('foo/bar')>>>'bar'/pPurePosixPath('bar/foo')当然也可以使用joinpath方法>>>PurePosixPath('/etc').joinpath('passwd')PurePosixPath('/etc/passwd')>>>PurePosixPath('/etc').joinpath(PurePosixPath('passwd'))PurePosixPath('/etc/passwd')>>>PurePosixPath('/etc').joinpath('init.d','apache2')PurePosixPath('/etc/init.d/apache2')>>>PureWindowsPath('c:').joinpath('/ProgramFiles')PureWindowsPath('c:/ProgramFiles')路径匹配>>>PurePath('a/b.py').match('*.py')True>>>PurePath('/a/b/c.py').match('b/*.py')True>>>PurePath('/a/b/c.py').match('a/*.py')Falsepathlib背景及待解决问题pathlib的目的是提供一个简单的类层次结构来处理文件系统的路径,同时提供通用路径-相关操作那么为什么不为此使用os模块或os.path呢?许多人更喜欢使用日期时间模块提供的高级对象来处理日期和时间,而不是使用数字时间戳和时间模块API。出于同样的原因,最好使用专用类来表示文件系统路径。换句话说,os.path是程序化的,而pathlib是面向对象的。Python也慢慢地从复制C的API转向围绕各种通用函数提供更好、更有用的抽象。在其他方面,也需要使用专门的类来处理特定的需求,比如Windows路径是不区分大小写的。在这种情况下,pathlib被添加到Python3.4的标准库中。pathlib的优点和缺点是什么?pathlib的优点是考虑了Windows路径的特殊性,提供了有和没有I/O操作的类。使用场景更清晰,API调用更易懂。先看一下pathlib对类的划分:图中箭头表示继承自,比如Path继承自PurePath,PurePath代表一个纯路径类,只提供对路径的常用操作,不包括实际的I/O操作,相对安全;Path包含PurePath的全部功能,包括I/O操作。PurePath有两个子类,一个是PureWindowsPath,代表Windows下的路径,不区分大小写,另一个是PurePosixPath,代表其他系统的路径。使用PureWindowsPath,你可以这样比较路径:frompathlibimportPureWindowsPath>>>PureWindowsPath('a')==PureWindowsPath('A')TruePurePath可以在任何操作系统上实例化,这意味着它与平台无关,你可以在unix系统上使用UsePureWindowsPath,在Windows系统上使用PurePosixPath,两者可以相互比较。>>>frompathlibimportPurePosixPath,PureWindowsPath,PosixPath>>>PurePosixPath('a')==PurePosixPath('b')False>>>PurePosixPath('a')>>PurePosixPath('a'')==PosixPath('a')True>>>PurePosixPath('a')==PureWindowsPath('a')False可以看出同一个类可以相互比较,不同的比较结果类是假的。相比之下,包含I/O操作的类PosixPath和WindowsPath只能在对应平台实例化:In[8]:frompathlibimportPosixPath,WindowsPathIn[9]:PosixPath('a')Out[9]:PosixPath('a')In[10]:WindowsPath('a')-------------------------------------------------------------------------NotImplementedErrorTraceback(mostrecentcallast)---->1WindowsPath('a')/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/pathlib.pyin__new__(cls,*args,**kwargs)1038self=cls._from_parts(args,init=False)1039ifnotself._flavour.is_supported:->1040raiseNotImplementedError("cannotinstantiate%ronyoursystem"1041%(cls.__name__,))1042self._init()NotImplementedError:cannotinstantiate'WindowsPath1onyoursystem]:systemIn[缺点,如果有的话,是在选择课程时会造成混淆。使用哪一个?其实不确定的话,可以用Path。这也是它的名字最短的原因,因为它更常用。更短的名字写起来更快。适用场景如果要处理文件系统相关的操作,选择pathlib。一些关键点获取home目录:In[70]:frompathlibimportPathIn[71]:Path.home()Out[71]:PosixPath('/Users/aaron')获取父目录的层级:>>>p=PureWindowsPath('c:/foo/bar/setup.py')>>>p.parents[0]PureWindowsPath('c:/foo/bar')>>>p.parents[1]PureWindowsPath('c:/foo')>>>p.parents[2]PureWindowsPath('c:/')获取多个文件后缀:>>>PurePosixPath('my/library.tar.gar').suffixes['.tar','.gar']>>>PurePosixPath('my/library.tar.gz').suffixes['.tar','.gz']>>>PurePosixPath('my/library').suffixes[]Windows样式Posix:>>>>p=PureWindowsPath('c:\\windows')>>>str(p)'c:\\windows'>>>p.as_posix()'c:/windows'获取uri文件:>>>p=PurePosixPath('/etc/passwd')>>>p.as_uri()'file:///etc/passwd'>>>p=PureWindowsPath('c:/Windows')>>>p.as_uri()'file:///c:/Windows'判断是否为绝对路径:>>>PurePosixPath('/a/b').is_absolute()True>>>PurePosixPath('a/b').is_absolute()False>>>PureWindowsPath('c:/a/b').is_absolute()True>>>PureWindowsPath('/a/b').is_absolute()False>>>PureWindowsPath('c:').is_absolute()False>>>PureWindowsPath('//some/share').is_absolute()True如果文件名改变:>>>p=PureWindowsPath('c:/Downloads/pathlib.tar.gz')>>>p.with_name('setup.py')PureWindowsPath('c:/Downloads/setup.py')很方便?pathlib技术的底层原理和关键实现并不是基于str,而是基于对象设计,严格区分Path对象和string对象,同时也使用了一些os函数,如os.name、os.getcwd等。您可以阅读pathlib的源代码以了解更多相关信息。最后,本文分享一下pathlib的使用方法。后面要处理路径相关操作的时候,第一时间想到的应该是pathlib,不知道怎么用没关系,在搜索引擎搜索pathlib就可以看到具体的使用方法.虽然pathlib比os库更高级更方便,提供了很多方便的功能,但是我们仍然需要知道如何使用os库,因为os库是Python中最强大最基础的库之一。但是,当我们需要对一些文件系统进行操作时,强烈推荐使用pathlib。本文转载自微信公众号“Python7号”,可通过以下二维码关注。转载本文请联系Python七号公众号。

最新推荐
猜你喜欢