在Linux上如果我们要操作文件、目录,可以在命令行下面输入操作系统提供的各种命令来完成,比如dir、cp等命令。
在Python程序中执行这些目录和文件的操作可以使用python提供的os或sys模块(注意os模块的某些函数是跟操作系统相关的如os.uname()是提供给Linux系统的)。其实操作系统提供的命令只是简单地调用了操作系统提供的接口函数,Python内置的os或sys模块也可以直接调用操作系统提供的接口函数。
os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口。sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
一、os模块
- 系统相关
os.name:查看系统名称,如果是posix表示系统是Linux、unix或mac,如果是nt就是wd。
os.uname():打印系统信息。
os.environ:打印全部变量值以字典的方式显示。
os.getenv(‘PATH’):打印单个环境变量值。
os.putenv(“PATH”, “/usr/local/bin”) :添加环境变量。
os.unsetenv(“PATH”):删除环境变量。
os.system(‘command’):执行系统命令。
os.popen(“dir”).read():执行命令并读取结果。
os.cpu_count():获取系统CPU核心数。
os.getlogin():返回登录用户。
os.sep:返回操作系统特定的路径分隔符,win下为”\\”,Linux下为”/”。
os.pathsep:返回用于分割PATH变量的字符串。
os.urandom(10):n字节用以加密的随机字符。
- 文件相关
os.chdir(‘/etc’):改变工作目录。
os.mkdir(‘/tmp/dir’):创建目录。
os.listdir(‘/tmp’):列出指定目录下的目录和文件。
os.mkdirs(‘/tmp/dir’):创建多级目录。
os.chroot(‘/’):设置当前进程的根目录。
os.getcwd():获取当前目录。
os.redir(‘/tmp’):删除空目录。
os.removedirs():删除多级目录。
os.rename(src, dst):重命名文件或目录。
os.stat():返回文件状态信息,比如大小、权限、属主属组等。
os.mkfifa():创建命名管道。
os.mknod():创建设备文件。
os.remove():删除文件。
os.unlink():删除链接文件。
os.symlink():创建符号链接。
os.utime():更新文件的时间戳。
os.tmpfile():创建并打开一个新的临时文件。
os.access():验证文件是否有此权限。
os.chmod():修改文件权限。
os.chown():修改文件属主属组。
os.umask():设置默认权限的遮罩码。
os.open():打开文件。
os.read():读取文件。
os.write():写文件。
os.nkdev():创建设备并指定主次设备号。
os.major():指定设备获取主设备号。
os.minor():指定设备获取次设备号。
os.fsencode(r””):(编码) 文件路径字符串转为bytes类型。
1 2 |
>>> os.fsencode(r"/tmp") b'/tmp' |
os.fsdecode(b””): (解码) 文件路径转为strs类型。
1 2 |
>>> os.fsdecode(b"/tmp") '/tmp' |
os.scandir() :DirEntry迭代器,文件目录。
1 2 3 4 5 6 7 8 |
for dir in os.scandir(): dir.name # 文件名 dir.path # 完整路径名 dir.inode() # inode编号 dir.is_dir() # 是否是文件夹 dir.is_file() # 是否是文件 dir.is_symlink() # 是否是链接 dir.stat() # 状态信息的stat_result对象 |
os.walk():生成一个目录树下的所有文件名,相当于tree命令。
语法:os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
其中top表示需要遍历的目录树的路径。topdown的默认值是”True”,表示首先返回目录树下的文件,然后在遍历目录树的子目录。Topdown的值为”False”时,则表示先遍历目录树的子目录,返回子目录下的文件,最后返回根目录下的文件。onerror的默认值是”None”,表示忽略文件遍历时产生的错误。如果不为空,则提供一个自定义函数提示错误信息后继续遍历或抛出异常中止遍历。
该函数返回一个元组,该元组有3个元素,这3个元素分别表示每次遍历的路径名,目录列表和文件列表。
1 2 3 4 5 6 7 8 9 10 11 |
>>> for root, dirs, files in os.walk("/tmp", topdown=False): ... for name in files: ... print(os.path.join(root, name)) #打印文件绝对路径; ... for name in dirs: ... print(os.path.join(root, name)) #打印目录绝对路径; ... /tmp/a/a.txt /tmp/b/b.txt /tmp/a.txt /tmp/a /tmp/b |
- 路径相关
os.path.basename():取路径基名。
1 2 |
>>> os.path.basename('/tmp/1.txt') '1.txt' |
os.path.dirname():路径目录名。
1 2 |
>>> os.path.dirname('/tmp/1.txt') '/tmp' |
os.path.abspath():返回path规范化的绝对路径。
1 2 3 4 |
>>> os.path.abspath('1.txt') '/root/1.txt' >>> os.path.abspath('../../1.txt') '/1.txt' |
os.path.join():整合文件名。
1 2 |
>>> os.path.join('/tmp', '1.txt') '/tmp/1.txt' |
os.path.split():将path分割成目录和文件名二元组返回。
1 2 |
>>> os.path.split('/tmp/1.txt') ('/tmp', '1.txt') |
os.path.splitext():返回文件名,扩展名元祖。
1 2 |
>>> os.path.splitext('/tmp/1.txt') ('/tmp/1', '.txt') |
os.path.getatime():获取目录访问时间。
os.path.getctime():获取目录改变时间。
os.path.getmtime():获取目录修改时间。
1 2 3 4 5 6 |
>>> os.path.getatime('/tmp') 1517993252.3505723 >>> os.path.getctime('/tmp') 1517993161.9352357 >>> os.path.getmtime('/tmp') 1517993161.9352357 |
os.path.getsize():获取目录大小。
1 2 |
>>> os.path.getsize('/tmp') 83 |
os.path.exists():判断指定目录是否存在。
1 2 3 4 |
>>> os.path.exists('/tmp/1.txt') False >>> os.path.exists('/tmp/') True |
os.path.isabs():判断指定的路径是否为绝对路径。
1 2 3 4 |
>>> os.path.isabs('/tmp') True >>> os.path.isabs('../') False |
os.path.isdir():判断是否为目录。
1 2 |
>>> os.path.isdir('/tmp/') True |
os.path.isfile():判断是否为文件。
1 2 |
>>> os.path.isfile('/tmp') False |
os.path.islink():判断是否为link文件。
1 2 |
>>> os.path.islink('/tmp') False |
os.path.ismount():判断是否为挂载点。
1 2 |
>>> os.path.ismount('/data') True |
os.path.samefile():判断两个路径是否指向了同一个文件。
1 2 3 4 |
>>> os.path.samefile('/tmp', '/tmp') True >>> os.path.samefile('/tmp', '/usr') False |
- 进程相关
os.abort():结束当前进程。
os._exit(0):退出当前进程。
os.ctermid():返回进程控制终端的文件名。
os.getppid():返回当前父进程ID。
os.getpid():获取当前进程ID。
os.fork():创建一个进程。
os.kill(8480, signal.SIGTERM):终止进程(需要导入:signal) SIGINT (终止进程) / SIGTERM (终止进程) / SIGKILL (终止进程) / SIGALRM (闹钟信号)。
二、shutil模块
复制文件的函数居然在os模块中不存在!原因是复制文件并非由操作系统提供的系统调用。理论上讲,我们通过上一节的读写文件可以完成文件复制,只不过要多写很多代码。shutil模块提供了copyfile()的函数,你还可以在shutil模块中找到很多实用函数,它们可以看做是os模块的补充。
copyfile(src, dst):从源src复制到dst中去。当然前提是目标地址是具备可写权限(异常信息为IOException),如果当前的dst已存在的话就会被覆盖掉。
copymode(src, dst):只是会复制其权限其他的东西是不会被复制的。
copystat(src, dst):复制权限、最后访问时间、最后修改时间。
copy(src, dst) : 复制一个文件到一个文件或一个目录。
copy2(src, dst) :在copy上的基础上再复制文件最后访问时间与修改时间也复制过来了,类似于cp –p的东西。
move(src, dst) : 移动一个文件到一个目录。如果源和目标在同一路径,操作相当于是rename操作,只是改名。
shutil.disk_usage():获取当前目录磁盘信息,如total、used、free等信息。
copytree(olddir, newdir, True/Flase):把olddir拷贝一份newdir,如果第3个参数是True,则复制目录时将保持文件夹下的符号连接,如果第3个参数是False,则将在复制的目录下生成物理副本来替代符号连接。
三、sys模块
sys.argv[0]:命令行参数List,第一个元素是程序本身路径。
sys.modules.keys():返回所有已经导入的模块列表。
sys.exc_info():获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息。
sys.exit(n):退出程序,正常退出时exit(0)。
sys.hexversion:获取Python解释程序的版本值,16进制格式如:0x020403F0。
sys.version:获取Python解释程序的版本信息。
sys.maxint:最大的Int值。
sys.maxunicode:最大的Unicode值。
sys.modules:返回系统导入的模块字段,key是模块名,value是模块。
sys.path:返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值。
sys.platform:返回操作系统平台名称。
sys.stdout:标准输出。
sys.stdin:标准输入。
sys.stderr:错误输出。
sys.exc_clear():用来清除当前线程所出现的当前的或最近的错误信息。
sys.exec_prefix:返回平台独立的python文件安装的位置。
sys.byteorder:本地字节规则的指示器,big-endian平台的值是’big’,little-endian平台的值是’little’。
sys.copyright:记录python版权相关的东西。
sys.api_version:解释器的C的API版本。
四、pathlib模块
pathlib库在python 3.4以后已经成为标准库,基本上可以代替os.path来处理路径。它采用完全面对对象的编程方式。
- 列出所有子目录
1 2 3 |
>>> from pathlib import * >>> p = Path('/tmp') >>> [x for x in p.iterdir() if x.is_dir()] |
- 列出指定类型的文件
1 2 |
list(p.glob('**/*.txt')) [PosixPath('/tmp/a.txt'), PosixPath('/tmp/a/a.txt'), PosixPath('/tmp/b/b.txt')] |
或者直接写在一起
1 2 3 4 5 6 7 |
>>> txt = Path('/tmp').glob('**/*.txt') >>> for i in txt: ... print(i) ... /tmp/a.txt /tmp/a/a.txt /tmp/b/b.txt |
- 路径拼接
可以使用/符号来拼接路径
1 2 3 |
>>> p = Path(r'/tmp') >>> p / 'python' PosixPath('/tmp/python') |
- 路径计算
1 2 3 4 5 |
>>> p = Path('/tmp') >>> p == PurePosixPath('/tmp') True >>> PurePosixPath('/tmp') == PurePosixPath('/TMP') False |
- 编码解码
1 2 3 4 5 |
>>> p = PurePath('/tmp') >>> str(p) '/tmp' >>> bytes(p) b'/tmp' |
- 常用属性
1 2 3 4 5 6 7 8 9 10 11 12 13 |
>>> p = Path('/tmp/a/a.txt') # 取路径基名 >>> p.name 'a.txt' # 分解路径以元祖返回 >>> p.parts ('/', 'tmp', 'a', 'a.txt') # 获取父目录 >>> p.parent PosixPath('/tmp/a') |
- 常用方法
cwd():设置path对象为当前路径
1 2 3 |
>>> p = Path('/tmp') >>> p.cwd() PosixPath('/root') |
stat():获取文件或目录属性
1 2 |
>>> p.stat().st_ino 203635502 |
exists():判断文件或目录是否存在
1 2 |
>>> p.exists() True |
glob():列举文件
1 2 |
>>> list(p.glob('**/*.txt')) [PosixPath('/tmp/a.txt'), PosixPath('/tmp/a/a.txt'), PosixPath('/tmp/b/b.txt')] |
iterdir():如果path指向一个目录,则返回该目录下所有内容的生成器
1 |
>>> list(p.iterdir()) |
joinpath():拼接路径
1 2 |
>>> p.joinpath('a') PosixPath('/tmp/a') |
owner():获取文件所有者
1 2 |
>>> p.owner() 'root' |
resolve():获取绝对路径
1 2 3 |
>>> p = Path('.') >>> p.resolve() PosixPath('/root') |
rename(target):将该文件或目录重命名为给定的目标,目标可以是一个字符串或另一个路径对象
1 |
>>> Path('/tmp/a/a.txt').rename('/tmp/a/b.txt') |
mkdir(mode=0o777, parents=False):创建目录,如果存在则抛异常
1 |
>>> Path('/tmp/c').mkdir(0o644, parents=False) |
rmdir():删除目录,目录必须为空
1 |
>>> Path('/tmp/c').rmdir() |
touch(mode=0o777, exist_ok=True):创建空文件,存在则抛异常
1 |
>>> Path('/tmp/c.txt').touch() |
open(mode=’r’, buffering=-1, encoding=None, errors=None, newline=None):打开文件
1 2 3 4 5 |
# 写入 >>> Path('/tmp/c.txt').open('w').write('some text\n') # 读出 >>> Path('/tmp/c.txt').open('r').read() |
write_bytes():以二进制方式写入,文件不存在会自动创建
1 2 |
>>> P = Path('/tmp/c.txt') >>> p.write_bytes(b'Binary file contents') |
write_text():以字符串方式写入,文件不存在会自动创建
1 2 |
>>> P = Path('/tmp/c.txt') >>> p.write_text('some text') |
read_bytes():以二进制方式读出
1 2 3 |
>>> p = Path('/tmp/c.txt') >>> p.read_bytes() b'some text' |
read_text():以字符串方式读出
1 2 |
>>> p.read_text() 'some text' |
samefile():路径或字符串比较
1 2 3 4 5 |
>>> p = Path('/tmp/c.txt') >>> p.samefile('/tmp') False >>> p.samefile('/tmp/c.txt') True |
chmod():修改文件或目录权限
1 |
>>> Path('/tmp/c.txt').chmod(0o644) |
is_dir():判断是否是目录
is_file():判断是否是文件
is_symlink():判断是否是链接文件
is_block_device():判断是否是块文件
is_char_device():判断是否是字符设备
is_socket():判断是否是sock文件
<参考>
Python3操作系统与路径模块(os / os.path / pathlib)