python标准库OS模块详解
python标准库OS模块简介
os就是“operating system”的缩写,顾名思义,os模块提供的就是各种 Python 程序与操作系统进⾏交互的接⼝。通过使⽤os模块,⼀⽅⾯可以⽅便地与操作系统进⾏交互,另⼀⽅⾯页可以极⼤增强代码的可移植性。如果该模块中相关功能出错,会抛出OSError异常或其⼦类异常。
注意
如果是读写⽂件的话,建议使⽤内置函数open();
如果是路径相关的操作,建议使⽤os的⼦模块os.path;
如果要逐⾏读取多个⽂件,建议使⽤fileinput模块;
要创建临时⽂件或路径,建议使⽤tempfile模块;
要进⾏更⾼级的⽂件和路径操作则应当使⽤shutil模块。
当然,使⽤os模块可以写出操作系统⽆关的代码并不意味着os⽆法调⽤⼀些特定系统的扩展功能,但要
切记⼀点:⼀旦这样做就会极⼤损害代码的可移植性。
此外,导⼊os模块时还要⼩⼼⼀点,千万不要为了图调⽤省事⼉⽽将os模块解包导⼊,即不要使⽤from os import *来导⼊os 模块;否则os.open()将会覆盖内置函数open(),从⽽造成预料之外的错误。
2. 常⽤功能
注意,os模块中⼤多数接受路径作为参数的函数也可以接受“⽂件描述符”作为参数。
⽂件描述符:file descriptor,在 Python ⽂档中简记为 fd,是⼀个与某个打开的⽂件对象绑定的整数,可以理解为该⽂件在系统中的编号。
2.1 os.name
该属性宽泛地指明了当前 Python 运⾏所在的环境,实际上是导⼊的操作系统相关模块的名称。这个名称也决定了模块中哪些功能是可⽤的,哪些是没有相应实现的。
⽬前有效名称为以下三个:posix,nt,java。
其中posix是 Portable Operating System Interface of UNIX(可移植操作系统接⼝)的缩写。Linux 和
Mac OS 均会返回该值;nt全称应为“Microsoft Windows NT”,⼤体可以等同于 Windows 操作系统,因此 Windows 环境下会返回该值;java则是Java 虚拟机环境下的返回值。
因此在我的电脑(win10)上执⾏下述代码,返回值是nt:
>>> import os
>>> os.name
'nt'
⽽在 WSL(Windows Subsystem Linux,Windows 下的 Linux ⼦系统)上的结果则是:
>>> import os
>>> os.name
'posix'
查看sys模块中的sys.platform属性可以得到关于运⾏平台更详细的信息,在此不再赘述
2.viron
⽐如其中键为“HOMEPATH”(Windows 下,Linux 下为“HOME”)的项,对应的值就是⽤户主⽬录的路径。Windows 下,其
值为:
>>> os.environ["HOMEPATH"]
'd:\\justdopython'
Linux 下,其值为:
>>> os.environ["HOME"]
'/home/justdopython'
2.3 os.walk()
这个函数需要传⼊⼀个路径作为top参数,函数的作⽤是在以top为根节点的⽬录树中游⾛,对树中的每个⽬录⽣成⼀个由(dirpath, dirnames, filenames)三项组成的三元组。
其中,dirpath是⼀个指⽰这个⽬录路径的字符串,dirnames是⼀个dirpath下⼦⽬录名(除去“.”和“..”)组成的列表,filenames 则是由dirpath下所有⾮⽬录的⽂件名组成的列表。要注意的是,这些名称并不包含所在路径本⾝,要获取dirpath下某个⽂件或路径从top⽬录开始的完整路径,需要使⽤os.path.join(dirpath, name)。
注意最终返回的结果是⼀个迭代器,我们可以使⽤for语句逐个取得迭代器的每⼀项:
>>> for item in os.walk("."):
... print(item)
...
('.', ['do'], ['go_'])
('.\\do', ['IAmDirectory', 'python'], [])
('.\\do\\IAmDirectory', [], [])
('.\\do\\python', [], [''])
2.4 os.listdir()
“listdir”即“list directories”,列出(当前)⽬录下的全部路径(及⽂件)。该函数存在⼀个参数,⽤以指定要列出⼦⽬录的路径,默认为“.”,即“当前路径”。
函数返回值是⼀个列表,其中各元素均为字符串,分别是各路径名和⽂件名。
通常在需要遍历某个⽂件夹中⽂件的场景下极为实⽤。
⽐如定义以下函数:
def get_filelists(file_dir='.'):
list_directory = os.listdir(file_dir)
filelists = []
for directory in list_directory:
# os.path 模块稍后会讲到
if(os.path.isfile(directory)):
filelists.append(directory)
return filelists
该函数的返回值就是当前⽬录下所有⽂件⽽⾮⽂件夹的名称列表。
2.5 os.mkdir()
“mkdir”,即“make directory”,⽤处是“新建⼀个路径”。需要传⼊⼀个类路径参数⽤以指定新建路径的位置和名称,如果指定路径已存在,则会抛出FileExistsError异常。
该函数只能在已有的路径下新建⼀级路径,否则(即新建多级路径)会抛出FileNotFoundError异常。
相应地,在需要新建多级路径的场景下,可以使⽤os.makedirs()来完成任务。函数os.makedirs()执⾏的是递归创建,若有必要,会分别新建指定路径经过的中间路径,直到最后创建出末端的“叶⼦路径”。
⽰例如下:
>>> os.mkdir("test_os_mkdir")
>>> os.mkdir("test_os_mkdir")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileExistsError: [WinError 183] 当⽂件已存在时,⽆法创建该⽂件。: 'test_os_mkdir'
>>>
>>> os.mkdir("test_os_mkdir/test_os_makedirs/just/do/python/hello")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
FileNotFoundError: [WinError 3] 系统不到指定的路径。: 'test_os_mkdir/test_os_makedirs/just/do/python/hello'
>>>
>>> os.makedirs("test_os_mkdir/test_os_makedirs/just/do/python/hello")
2.ve()
⽤于删除⽂件,如果指定路径是⽬录⽽⾮⽂件的话,就会抛出IsADirectoryError异常。删除⽬录应该使⽤os.rmdir()函数。
同样的,对应于os.makedirs(),删除路径操作os.rmdir()也有⼀个递归删除的函数os.removedirs(),该函数会尝试从最下级⽬录开始,逐级删除指定的路径,⼏乎就是⼀个os.makedirs()的逆过程;⼀旦遇到⾮空⽬录即停⽌。
2.ame()
该函数的作⽤是将⽂件或路径重命名,⼀般调⽤格式为os.rename(src, dst),即将src指向的⽂件或路径重命名为dst指定的名称。
注意,如果指定的⽬标路径在其他⽬录下,该函数还可实现⽂件或路径的“剪切并粘贴”功能。但⽆论直接原地重命名还是“剪切粘贴”,中间路径都必须要存在,否则就会抛出FileNotFoundError异常。如果⽬标路径已存在,Windows 下会抛出FileExistsError异常;Linux 下,如果⽬标路径为空且⽤户权限允许,则会静默覆盖原路径,否则抛出OSError异常,
和上两个函数⼀样,该函数也有对应的递归版本os.renames(),能够创建缺失的中间路径。
注意,这两种情况下,如果函数执⾏成功,都会调⽤os.removedir()函数来递归删除源路径的最下级⽬录。
2.wd()
“getcwd”实际上是“get the current working directory”的简写,顾名思义,也就是说这个函数的作⽤是“获取当前⼯作路径”。在程序运⾏的过程中,⽆论物理上程序在实际存储空间的什么地⽅,“当前⼯作路径”即可认为是程序所在路径;与之相关的“相对路径”、“同⽬录下模块导⼊”等相关的操作均以“当前⼯作路径”为准。
在交互式环境中,返回的就是交互终端打开的位置;⽽在 Python ⽂件中,返回的则是⽂件所在的位置。
在 Windows 下会有如下输出:
>>> os.getcwd()
'd:\\justdopython\\just\\do\\python'
Linux 下的输出则是:
>>> os.getcwd()
'/home/justdopython/just/do/python'
2.9 os.chdir()
“chdir”其实是“change the directory”的简写,因此os.chdir()的⽤处实际上是切换当前⼯作路径为指定路径。其中“指定路径”需要作为参数传⼊函数os.chdir(),该参数既可以是⽂本或字节型字符串,也可以是⼀个⽂件描述符,还可以是⼀个⼴义的类路径(path-like)对象。若指定路径不存在,则会抛出FileNotFoundError异常。
在 Windows 下,调⽤该函数的效果为:
>>> os.chdir("d:/justdopython/just/do")
>>> os.getcwd()
'd:\\justdopython\\just\\do'
在 Linux 下的效果则是:
>>> os.chdir("/home/justdopython/just/do") # 也可将参数指定为"..",即可切换到⽗⽬录
>>> os.getcwd()
'/home/justdopython/just/do'
有了这个函数,跨⽬录读写⽂件和调⽤模块就会变得⾮常⽅便了,很多时候也就不必再反复将同⼀个⽂件在各个⽬录之间复制粘贴运⾏,脚本完全可以坐镇中军,在⼀个⽬录下完成对其他⽬录⽂件的操作,正所谓“运筹帷幄之中,决胜于千⾥之外”也。
举例来说,可以通过将“当前⼯作⽬录”切换到⽗⽬录,从⽽直接访问⽗⽬录的⽂件内容:
>>> os.chdir("..")
>>> os.getcwd()
'D:\\justdopython\\just'
>>> with open("", encoding="utf-8") as f:
... f.read()
...
'欢迎访问 justdopython,⼀起学习 Python 技术~'
>>> os.listdir()
['']
3. os.path 模块
其实这个模块是os模块根据系统类型从另⼀个模块导⼊的,并⾮直接由os模块实现,⽐如os.name值为nt,则在os模块中执⾏import ntpath as path;如果os.name值为posix,则导⼊posixpath。
使⽤该模块要注意⼀个很重要的特性:os.path中的函数基本上是纯粹的字符串操作。换句话说,传⼊该模块函数的参数甚⾄不需要是⼀个有效路径,该模块也不会试图访问这个路径,⽽仅仅是按照“路径”的通⽤格式对字符串进⾏处理。
更进⼀步地说,os.path模块的功能我们都可以⾃⼰使⽤字符串操作⼿动实现,该模块的作⽤是让我们在实现相同功能的时候不必考虑具体的系统,尤其是不需要过多关注⽂件系统分隔符的问题。
3.1 os.path.join()
这是⼀个⼗分实⽤的函数,可以将多个传⼊路径组合为⼀个路径。实际上是将传⼊的⼏个字符串⽤系统的分隔符连接起来,组合成⼀个新的字符串,所以⼀般的⽤法是将第⼀个参数作为⽗⽬录,之后每⼀个参数即使下⼀级⽬录,从⽽组合成⼀个新的符合逻辑的路径。
但如果传⼊路径中存在⼀个“绝对路径”格式的字符串,且这个字符串不是函数的第⼀个参数,那么其他在这个参数之前的所有参数都会被丢弃,余下的参数再进⾏组合。更准确地说,只有最后⼀个“绝对路径”及其之后的参数才会体现在返回结果中。
>>> os.path.join("just", "do", "python", "dot", "com")
'just\\do\\python\\dot\\com'
>>>
>>> os.path.join("just", "do", "d:/", "python", "dot", "com")
'd:/python\\dot\\com'
>>>
>>> os.path.join("just", "do", "d:/", "python", "dot", "g:/", "com")
'g:/com'
3.2 os.path.abspath()
将传⼊路径规范化,返回⼀个相应的绝对路径格式的字符串。
也就是说当传⼊路径符合“绝对路径”的格式时,该函数仅仅将路径分隔符替换为适应当前系统的字符,不做其他任何操作,并将结果返回。所谓“绝对路径的格式”,其实指的就是⼀个字母加冒号,之后跟分隔符和字符串序列的格式:
>>> os.path.abspath("a:/just/do/python")
'a:\\just\\do\\python'
>>> # 我的系统中并没有 a 盘
当指定的路径不符合上述格式时,该函数会⾃动获取当前⼯作路径,并使⽤os.path.join()函数将其与传⼊的参数组合成为⼀个新的路径字符串。⽰例如下:
>>> os.path.abspath("ityouknow")
'D:\\justdopython\\ityouknow'
3.3 os.path.basename()
python怎么读的该函数返回传⼊路径的“基名”,即传⼊路径的最下级⽬录。
>>> os.path.basename("/ityouknow/justdopython/IAmBasename")
'IAmBasename'
>>> # 我的系统中同样没有这么⼀个路径。可见 os.path.basename() 页是单纯进⾏字符串处理
整这个函数要注意的⼀点是,返回的“基名”实际上是传⼊路径最后⼀个分隔符之后的⼦字符串,也就是说,如果最下级⽬录之后还有⼀个分隔符,得到的就会是⼀个空字符串:
>>> os.path.basename("/ityouknow/justdopython/IAmBasename/")
''
3.4 os.path.dirname()
与上⼀个函数正好相反,返回的是最后⼀个分隔符前的整个字符串:
>>> os.path.dirname("/ityouknow/justdopython/IAmBasename")
'/ityouknow/justdopython'
>>>
>>> os.path.dirname("/ityouknow/justdopython/IAmBasename/")
'/ityouknow/justdopython/IAmBasename'
3.5 os.path.split()
哈哈实际上前两个函数都是弟弟,这个函数才是⽼⼤。
函数os.path.split()的功能就是将传⼊路径以最后⼀个分隔符为界,分成两个字符串,并打包成元组的形式返回;前两个函数os.path.dirname()和os.path.basename()的返回值分别是函数os.path.split()返回值的第⼀个、第⼆个元素。就连⼆者的具体实现都⼗分真实:
def basename(p):
"""Returns the final component of a pathname"""
return split(p)[1]
def dirname(p):
"""Returns the directory component of a pathname"""
return split(p)[0]
通过os.path.join()函数⼜可以把它们组合起来得到原先的路径。
3.6 ists()
这个函数⽤于判断路径所指向的位置是否存在。若存在则返回True,不存在则返回False:
>>> ists(".")
True
>>> ists("./just")
True
>>> ists("./Inexistence") # 不存在的路径
False
⼀般的⽤法是在需要持久化保存某些数据的场景,为避免重复创建某个⽂件,需要在写⼊前⽤该函数检测⼀下相应⽂件是否存在,若不存在则新建,若存在则在⽂件内容之后增加新的内容。
3.7 os.path.isabs()
该函数判断传⼊路径是否是绝对路径,若是则返回True,否则返回False。当然,仅仅是检测格式,同样不对其有效性进⾏任何核验:
>>> os.path.isabs("a:/justdopython")
True
3.8 os.path.isfile() 和 os.path.isdir()
这两个函数分别判断传⼊路径是否是⽂件或路径,注意,此处会核验路径的有效性,如果是⽆效路径将会持续返回False。>>> # ⽆效路径
>>> os.path.isfile("a:/justdopython")
False
>>>
>>> # 有效路径
>>> os.path.isfile("./just/plain_txt")
True
>>>
>>> # ⽆效路径
>>> os.path.isdir("a:/justdopython/")
False
>>> # 有效路径
>>> os.path.isdir("./just/")
True
4. 总结
本⽂详细介绍了与操作系统交互的os模块中⼀些常⽤的属性和函数,基本可以覆盖初阶的学习和使⽤。有了这些功能,我们已经可以写出⼀些⽐较实⽤的脚本了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论