os模块
1.os.path.join()方法
os.path.join()
在拼接路径的时候用的。
>> os.path.join(“home”, "me", "mywork")
#在Linux系统上会返回
“home/me/mywork"
2.os.path.expanduser(path)
把path中包含的""和"user"转换成用户目录
>>> os.path.expanduser('~')
'/home/l'
3.os.path.split()
将文件名和路径分割开
语法:os.path.split('PATH')
参数说明:
PATH指一个文件的全路径作为参数:
如果给出的是一个目录和文件名,则输出路径和文件名
如果给出的是一个目录名,则输出路径和为空文件名
实际上,该函数的分割并不智能,它仅仅是以 "PATH" 中最后一个 '/' 作为分隔符,分隔后,将索引为0的视为目录(路径),将索引为1的视为文件名,如
>>> import os
>>> os.path.split('C:/soft/python/test.py')
('C:/soft/python', 'test.py')
>>> os.path.split('C:/soft/python/test')
('C:/soft/python', 'test')
>>> os.path.split('C:/soft/python/')
('C:/soft/python', '')
4.os._exit() 和 sys.exit()
os._exit() vs sys.exit()
概述
python的程序有两中退出方式:os._exit(), sys.exit()。本文介绍这两种方式的区别和选择。
os._exit()会直接将python程序终止,之后的所有代码都不会继续执行。
sys.exit()会引发一个异常:SystemExit,如果这个异常没有被捕获,那么python解释器将会退出。如果有捕获此异常的代码,那么这些代码还是会执行。捕获这个异常可以做一些额外的清理工作。0为正常退出,其他数值(1-127)为不正常,可抛异常事件供捕获。
举例说明
import os, sys
try:
sys.exit(0)
except:
print('die')
finally:
print('cleanup')
控制台打印结果:
die
cleanup
例子
import os, sys
try:
os._exit(0)
except:
print('die')
print('os.exit')#不打印直接退出了
- 区别
综上,sys.exit()的退出比较优雅,调用后会引发SystemExit异常,可以捕获此异常做清理工作。os._exit()直接将python解释器退出,余下的语句不会执行。
一般情况下使用sys.exit()即可,一般在fork出来的子进程中使用os._exit()
一般来说os._exit() 用于在线程中退出
sys.exit() 用于在主线程中退出。
exit() 跟 C 语言等其他语言的 exit() 应该是一样的。
os._exit() 调用 C 语言的 _exit() 函数。
builtin.exit 是一个 Quitter 对象,这个对象的 call 方法会抛出一个 SystemExit 异常。
- exit(0)和exit(1)
exit(0):无错误退出
exit(1):有错误退出
退出代码是告诉解释器的(或操作系统)
5.os.environ()
key字段详解
windows:
os.environ['HOMEPATH']:当前用户主目录。
os.environ['TEMP']:临时目录路径。
os.environ[PATHEXT']:可执行文件。
os.environ['SYSTEMROOT']:系统主目录。
os.environ['LOGONSERVER']:机器名。
os.environ['PROMPT']:设置提示符。
linux:
os.environ['USER']:当前使用用户。
os.environ['LC_COLLATE']:路径扩展的结果排序时的字母顺序。
os.environ['SHELL']:使用shell的类型。
os.environ['LAN']:使用的语言。
os.environ['SSH_AUTH_SOCK']:ssh的执行路径。
6.os.path.abspath(file)
import os
app_root = '/'.join(os.path.abspath(__file__).split('/'))
print(app_root)
app_root = os.path.dirname(__file__)
print(app_root)
控制台打印结果
/usr/bin/python3.6 /home/l/PycharmProjects/Test/exercise.py
/home/l/PycharmProjects/Test/exercise.py
/home/l/PycharmProjects/Test
7.os.walk的用法
(1)载入
要使用os.walk,首先要载入该函数
可以使用以下两种方法
import os
from os import walk
(2)使用
os.walk的函数声明为:
walk(top, topdown=True, onerror=None, followlinks=False)
参数
top 是你所要便利的目录的地址
topdown 为真,则优先遍历top目录,否则优先遍历top的子目录(默认为开启)
onerror 需要一个 callable 对象,当walk需要异常时,会调用
followlinks 如果为真,则会遍历目录下的快捷方式(linux 下是 symbolic link)实际所指的目录(默认关闭)
返回值
os.walk 的返回值是一个生成器(generator),也就是说我们需要不断的遍历它,来获得所有的内容。
每次遍历的对象都是返回的是一个三元组(root,dirs,files)
root 所指的是当前正在遍历的这个文件夹的本身的地址
dirs 是一个 list ,内容是该文件夹中所有的目录的名字(不包括子目录)
files 同样是 list , 内容是该文件夹中所有的文件(不包括子目录)
如果topdown 参数为真,walk 会遍历top文件夹,与top文件夹中每一个子目录。
例子
如果我们有如下的文件结构:
a -> b -> 1.txt, 2.txt
c -> 3.txt
d ->
4.txt
5.txt
for (root, dirs, files) in os.walk('a'):
#第一次运行时,当前遍历目录为 a
所以 root == 'a'
dirs == [ 'b', 'c', 'd']
files == [ '4.txt', '5.txt']
。。。
# 接着遍历 dirs 中的每一个目录
b: root = 'a\\b'
dirs = []
files = [ '1.txt', '2.txt']
# dirs为空,返回
# 遍历c
c: root = 'a\\c'
dirs = []
files = [ '3.txt' ]
PS : 如果想获取文件的全路径,只需要
for f in files:
path = os.path.join(root,f)
# 遍历d
d: root = 'a\\b'
dirs = []
files = []
遍历完毕,退出循环
(3)简单的例子
保持目录 a 的目录结构,在 b 中创建对应的文件夹,并把a中所有的文件加上后缀 _bak
import os
Root = 'a'
Dest = 'b'
for (root, dirs, files) in os.walk(Root):
new_root = root.replace(Root, Dest, 1)
if not os.path.exists(new_root):
os.mkdir(new_root)
for d in dirs:
d = os.path.join(new_root, d)
if not os.path.exists(d):
os.mkdir(d)
for f in files:
# 把文件名分解为 文件名.扩展名
# 在这里可以添加一个 filter,过滤掉不想复制的文件类型,或者文件名
(shotname, extension) = os.path.splitext(f)
# 原文件的路径
old_path = os.path.join(root, f)
new_name = shotname + '_bak' + extension
# 新文件的路径
new_path = os.path.join(new_root, new_name)
try:
# 复制文件
open(new_path, 'wb').write(open(old_path, 'rb').read())
except IOError as e:
print(e)
检查某个文件是否存在
下面的代码可以说是检查文件是否存在以及其是否为文件的最简单方法。
import os
os.path.isfile('./file.txt') # True
os.path.isfile('./link.txt') # True
os.path.isfile('./fake.txt') # False
os.path.isfile('./dir') # False
os.path.isfile('./sym') # False
os.path.isfile('./foo') # False
注意os.path.isfile
能够追踪符号链接(symlinks),所以在检查link.txt
时得到的结果是True
。
isfile
实际上只是一个辅助方法(helper method),其内部使用了os.stat
和stat.S_ISREG(mode)
,稍后再详细介绍。
检查某个文件夹是否存在
与isfile
方法类似,os.path.isdir
是检查某个文件夹是否存在或者某个给定路径是否是文件夹的最简单方法。
import os
os.path.isdir('./file.txt') # False
os.path.isdir('./link.txt') # False
os.path.isdir('./fake.txt') # False
os.path.isdir('./dir') # True
os.path.isdir('./sym') # True
os.path.isdir('./foo') # False
同样,os.path.isdir
也能够追踪符合链接。它也只是一个简单的辅助函数,其底层调用了os.stat
和stat.S_ISDIR(mode)
。
检查是否存在文件或文件夹
检查某个路径(前提是你不关心其指向的是文件还是文件夹)是否存在的另一种方法,是使用os.path.exists
。
import os
os.path.exists('./file.txt') # True
os.path.exists('./link.txt') # True
os.path.exists('./fake.txt') # False
os.path.exists('./dir') # True
os.path.exists('./sym') # True
os.path.exists('./foo') # False
这个函数不关心路径指向的是文件、文件夹还是符号链接,因此这就好像你在使用的是isfile(path)
或isdir(path)
。但实际上,它调用的是os.stat(path)
,如果出错的话它会返回False
。
高级方法
上面我一直在说那些方法利用了os.stat
模块,因此我觉得详细了解下这个模块是有好处的。这是一个底层方法,可以提高关于文件、文件夹、套接字、缓存等的详细信息。
和前面提到的两种方法一样,os.stat
也会追踪符号链接,因此如何你想获得某个链接的状态信息,应该使用的是os.lstat()
方法。
由于操作系统之间存在差异,os.stat
提供的数据可能有所区别。下面是每个操作系统都会提供的一些数据:
st_mode: protection bits
st_uid: owner's user id
st_gid: owner's group id
st_size: size of file in bytes
st_atime: time of last access
st_mtime: time of last modification
st_ctime: time of last metadata change on Unix, or time of creation on Windows
你可以使用stat
模块提供的这些数据,获取自己感兴趣的信息,比如说某个路径是否指向一个套接字(stat.S_ISSOCK(mode)
),或则是某个文件是不是其实只是一个有命名的管道(stat.S_ISFIFO(mode)
)。
如果你需要更高级的功能,那么应该使用os.stat
这个模块。但是大部分情况下,你只需要使用os
或os.path
中的模块就足够了。