介绍
利用os.path模块中包含的函数,很容易编写代码来处理多个平台上的文件
解析路径
import os.path
'''
os.path中的第一组函数可以用来将表示文件名的字符串解析为文件名的各个组成部分。
这些函数并不要求路径真正存在:它们只是处理字符串。
'''
# os.sep:路径各部分之间的分隔符,例如/或者\
print(os.sep) # \
# os.extsep:文件与文件扩展名之间的分隔符
print(os.extsep) # .
# os.pardir:路径中表示目录树上一级的部分
print(os.pardir) # ..
# os.curdir:路径中表示当前目录的部分
print(os.curdir) # .
# split函数:将路径分解为两个部分,返回包含结果的元组
print(os.path.split(r"C:\python37")) # ('C:\\', 'python37')
print(os.path.split(r"C:\python37\python.exe")) # ('C:\\python37', 'python.exe')
# split函数的两部分,分别等价于dirname和basename
print(os.path.dirname(r"C:\python37"), "--", os.path.basename(r"C:\python37")) # C:\ -- python37
print(os.path.dirname(r"C:\python37\python.exe"), "--",
os.path.basename(r"C:\python37\python.exe")) # C:\python37 -- python.exe
'''
可以看到是以最后一个目录分隔符为基准的,C:\\aaa\\bbb\\ccc\\ddd, --> C:\\aaa\\bbb\\ccc ddd
'''
# 还有一个splitext函数,和split类似,但是是以扩展名分隔符为基准的
# 既然是以扩展名为基准,那么必须是文件才会有意义。
print(os.path.splitext(r"C:\python37")) # ('C:\\python37', '')
# 可以看到这里是个目录,因此得到('C:\\python37', '')。
# 但是之前也说过,这些函数不要求文件真的存在,而是把当成字符串像文件名一样处理
# 表示C盘下有一个python3.7文件,.7表示扩展名
print(os.path.splitext(r"C:\python3.7")) # ('C:\\python3', '.7')
print(os.path.splitext(r"C:\python37\python.exe")) # ('C:\\python37\\python', '.exe')
# 如果有多个扩展名分隔符,比如linux下的gz包,那么一最后一个扩展名分隔符为基准
print(os.path.splitext(r"C:\python37\hadoop.tar.gz")) # ('C:\\python37\\hadoop.tar', '.gz')
# 还记得os.path.split吗?是以目录分隔符为基准的,用它来分解会有什么效果呢
print(os.path.split(r"C:\python37\hadoop.tar.gz")) # ('C:\\python37', 'hadoop.tar.gz')
# commonprefix取一个路径列表作为参数,并且返回一个字符串,表示所有路径都出现的公共前缀
path = [r"C:\Go", r"C:\MinGW", r"C:\python37"]
print(os.path.commonprefix(path)) # C:\
print(os.path.commonprefix(path + [r"F:\\mmp"])) # 这里返回了一个空字符串,因为没有公共前缀
# 不过还有一个隐藏的问题
path = [r"C:\1\2\3", r"C:\1\2\4", r"C:\1\23\5"]
# 注意这里打印的是C:\1\2,所以这个函数没有考虑路径分隔符,是真的当成是字符串来处理,r"C:\1\23\5",把23没有作为整体处理
print(os.path.commonprefix(path)) # C:\1\2
# 那如何避免这种情况呢?可以使用commonpath,专门是解决这种情况的
print(os.path.commonpath(path)) # C:\1
建立路径
import os.path
'''
除了分解现有的路径,还经常需要从其他字符串建立路径。要将多个路径组成部分结合为一个值,可以使用join
'''
print(os.path.join("a", "b", "c")) # a\b\c
# ~表示家目录,expanduser可以自动识别
print(os.path.expanduser("~")) # C:\Users\satori
print(os.path.join(os.path.expanduser("~"), "666", "1.txt")) # C:\Users\satori\666\1.txt
# expandvars更为通用,因为它会扩展路径中出现的所有变量
import os
os.environ["Sherry"] = "啊,雪莉" # 设置环境变量
# 那么可以使用$的形式,类似于shell
print(os.path.expandvars(r"C:\python37\$Sherry")) # C:\python37\啊,雪莉
规范化路径
import os.path
'''
使用join或利用嵌入变量由单独的字符串组合路径时,得到的路径最后可能会有多余的分隔符或相对路径部分。使用normpath可以清除这些内容
'''
print(os.path.normpath(r"one\..\two\.\three")) # two\three
# 把相对路径转换为绝对路径,可以使用abspath
path = r"C:\python37\Lib\asyncio\..\.."
print(os.path.abspath(path)) # C:\python37
文件时间
import os.path
import time
'''
除了处理文件路径,os.path还包括一些用于获取文件属性的函数,类似于os.stat函数返回的结果
'''
# os.path.getatime返回文件的访问时间,a:access
print(time.strftime("%Y-%m-%d %X", time.localtime(os.path.getatime(__file__)))) # 2019-03-20 11:46:58
# os.path.getmtime返回文件的修改时间,m:modify
print(time.strftime("%Y-%m-%d %X", time.localtime(os.path.getmtime(__file__)))) # 2019-03-20 11:46:58
# os.path.getctime返回文件的创建时间,c:create
print(time.strftime("%Y-%m-%d %X", time.localtime(os.path.getctime(__file__)))) # 2019-03-19 17:17:52
# 返回的是一个时间戳,需要使用time.localtime转换为时间元祖,然后再用strftime转成字符串的格式
测试文件
import os.path
'''
程序在遇到一个路径时,需要知道这个路径到底一个文件、目录还是一个符号链接,以及这个路径到底存在与否。
os.path包含了一些用于测试这些条件的函数
'''
file = r"C:\python37\Lib\asyncio\base_events.py"
dir = r"C:\python37\Lib\asyncio"
# 是否是绝对路径
print(os.path.isabs(file)) # True
# 判断是否是一个文件
print(os.path.isfile(file)) # True
print(os.path.isfile(dir)) # False
# 判断是否是一个目录
print(os.path.isdir(file)) # False
print(os.path.isdir(dir)) # True
# 判断是否是一个链接
print(os.path.islink(file)) # False
# 判断是否是一个挂载
print(os.path.ismount(file)) # False
# 判断是否存在
print(os.path.exists(file)) # True