os模块
一、什么是os模块
os模块提供了多数操作系统的功能接口函数 当os模块被导入后,它会自适应于不同的操作系统平台,根据不同的平台进行相应的操作,在python编程时,经常和文件、目录打交道,所以离不了os模块。
导入os模块
import os
二、常用的os模块命令
os.name
os.name ——name顾名思义就是’名字’,这里的名字是指操作系统的名字,主要作用是判断目前正在使用的平台,并给出操作系统的名字,如Windows 返回 ‘nt’ ; Linux 返回’posix’ 。
注意该命令不带括号,它是一个属性,除了第一个命令不带括号之外,以下命令基本都带括号。
print(os.name)
os.getcwd()
os.getcwd() ——全称应该是’get current work directory’,获取当前工作的目录,如:返回结果为:‘C:\Program Files\Python36’。
等于linux中命令的pwd
print(os.getcwd())
os.listdir(dir)
os.listdir(path) ——列出path目录下所有的文件和目录名,返回一个给定path下所有文件的一个列表。相当于linux中的ls
path参数可以省略,如果省略,则默认返回当前目录下所有文件
print(os.listdir())
print(os.listdir('./numpy练习/'))
以列表的形式全部列举出来,其中没有区分目录和文件。
合并/拆分路径
os库中支持对路径的拆分和合并
os中认为每一个路径都由文件路径(dirname)和文件名(basename)所组成:
它们由最后一个’/’分隔,最后一个’/’之后的即为文件名(注意它可以是一个dir也可以是一个file) 以此衍生的功能就是对文件路径和文件名的拆分(path.split)和合并(path.join)
以下例子中我们都以名为’python文件’的目录下的test目录为例
pathname = './python文件/test'
os.path.dirname(path)
os.path.dirname(path) ——返回文件路径
print(os.path.dirname(pathname))
返回该文件所在的母目录,即’/’之前的文件路径
os.path.basename(path)
os.path.basename(path)——返回文件名
print(os.path.basename(pathname))
返回该文件的名字
os.path.split(path)
os.path.split(path)——返回路径的(目录,文件名)的tuple,即将目录和文件名分开,而不是一个整体。
此处只是把前后两部分分开成(dirname, basename)而已。就是找最后一个’/’。
print(os.path.split(pathname))
os.path.join(path, name)
os.path.join(path, name)——连接目录和文件名,与os.path.split(path)相对。其作用是在某个文件所在的文件夹中创建其他文件时可利用先拆分得到母目录(dirname),然后再合并一个新文件名得到新path。
parent, _ = os.path.split(pathname)
print(parent)
new_filename = 'new_test'
print(os.path.join(parent,new_filename))
思考为什么要这么麻烦先拆再合
拿到母目录parent不可以直接使用parent = os.getcwd()吗
注意这样的想法是不对的,os.getcwd()的目录是你当前py文件所在的路径,比如说我上面的py文件是在桌面上创建的,所以拿到的是c:\Users\123\Desktop。而我是想在pathname这个文件所在的’./python文件’的母目录中创建。所以必须要先拆分后合并。
当然下面介绍的chdir可以改变当前路径后再用os.getcwd()也是可以的,不过就麻烦一些了
创建/删除文件夹dir
注意下面的命令都是对目录层面操作
输入参数的dir都为一个文件夹地址,如果输入一个文件地址则会报错
os.mkdir(dir)
os.mkdir(path) ——创建path指定的目录,该参数不能省略。
等于linux命令中的mkdir
注意mkdir只能创建目录,想创建文件时加上特定后缀也是不可以的,
例如,如果想创建一个’test.txt’的文本文件,os.mkdir(‘test.txt’)后只能创建名为’test.txt’的为文件夹
path = './python文件/'
new_dir_name = 'testdir'
newdir = os.path.join(path,new_dir_name)
os.mkdir(newdir)
os.makedirs(recur_dirs)
注意:os.mkdir(path) 只能建立一层目录,要想递归创建多层目录可用:os.makedirs()
muti_dir = './python文件/test2/test2.1'
os.makedirs(muti_dir)
os.rmdir(empty_dir)
os.rmdir(path) ——删除path指定的单个空文件夹,该参数不能省略。
如果删除非空文件夹会报错 “目录不是空的。”
注意:只要文件夹里有任何内容就是非空文件夹
一个文件夹不管是包含了空文件夹还是空文件,只要包含了任何内容就是非空文件夹
newdir = './python文件/testdir'
os.rmdir(newdir)
shutil.rmtree(recur_dirs)
os库中并不支持删除非空文件夹,如果想像linux中 rm -r dir 的命令一样删除文件夹中所有的内容的话,要利用shutil库。shutil.rmtree的命令像删除树一样递归的删除该dir以及该dir下所有的内容。
import shutil
shutil.rmtree(none_empty_dirs)
创建/删除文件file
注意下面的命令都是对文件层面操作
输入参数的file都为一个文件夹地址,如果输入一个文件夹地址则会报错
open(file,‘w’)
wins创建空文件只有这种方式,os库中的创建文件函数不能用在wins下
newfile = './python文件/666.txt'
open(newfile, 'w')
os.mknod(file)
该函数只能用在linux中,windows没有node的概念,所以不支持
os.mknod(path) ——创建path指定的空文件,该参数不能省略。
os.remove(file)
os.remove(path) ——删除path指定的文件,该参数不能省略。
等于linux中的rm filename 的指令
filepath = './python文件/666.txt'
os.remove(filepath)
其他常用指令
os.path.isfile(path)
os.path.isfile(path) ——判断指定对象是否为文件。是返回True,否则False
os.path.isdir(path)
os.path.isdir(path) ——判断指定对象是否为目录。是True,否则False。
os.path.exists(path)
os.path.exists(path) ——检验指定的对象是否存在。是True,否则False.例
os.chdir(path)
os.chdir(path) ——'change dir’改变目录到指定目录
等于linux中的cd 命令
print(os.getcwd())
os.chdir('./python文件/')
print(os.getcwd())
os.path.getsize()
os.path.getsize() ——获得文件的大小,如果为目录,返回0
os.path.abspath(path)
os.path.abspath(path) ——输入一个文件路径,获得其绝对路径。
path = './python文件/'
print(os.path.abspath(path))
sys库
一、sys库介绍以及常见函数列表
sys模块包括了一组非常实用的服务,内含很多函数方法和变量,用来处理Python运行时配置以及资源,从而可以与前当程序之外的系统环境交互,如:python解释器。
import sys
当Python执行import sys语句的时候,它在sys.path变量中所列目录中寻找sys.py模块。如果找到了这个文件,这个模块的主块中的语句将被运行,然后这个模块将能够被你 使用 。注意,初始化过程仅在我们 第一次 输入模块的时候进行。另外,“sys”是“system”的缩写。
Sys模块函数之多,我只能选取自己认为比较实用的一些函数列在此处。借马云找员工的说法,”找最合适的而不是最天才的”,这句话,我个人觉得在很多方面都能适应,学习也不在话下。Sys模块功能的确很多,但我们应该将重点放在那些功能才是最适合我们的,为此,我列的这些函数,就是我认为比较适合我以后开发的函数。
二、sys常用函数介绍
sys.argv
很多人会想,如何给我的程序在外部传递参数到我的程序中呢呢?这个就可以用sys.argv实现。如:test.py
import sys
args = sys.argv
print(args)
注意:sys.argv 命令是个sys模块中的属性,调用时不需要括号
sys.argv 其实就是一个列表,里边的项为用户输入的参数,关键就是要明白这参数是从程序外部输入的,而非代码本身的什么地方,要想看到它的效果就应该将程序保存了,从外部来运行程序并给出参数。
(base) C:\Users\123\Desktop>python test.py 1 2 3
>>> ['test.py', '1', '2', '3']
看到对应的关系了吗?
sys.argv 变量是一个字符串的列表,这意味着即使命令行敲入的是数字也是字符串类型。特别地,sys.argv 包含了命令行参数的列表,即使用命令行传递给你的程序的参数,传入参数时,各参数用空格分隔。
注意,脚本的名称总是sys.argv 列表的第一个参数即sys.argv[0] 。
所以,在这各例子中,'test.py’是sys.argv[0] 、'1’是sys.argv[1] 、'2’是sys.argv[2] 以及’3’是sys.argv[3] 。
所以一般为了拿到所有参数我们一般提取sys.argv[1:]
import sys
args = sys.argv[1:]
sys.platform
显示当前的操作系统类别。这就相当于os中的os.name 与os.name 一样,是一个属性,调用时不需要括号。
假设,我们想实现一个清除终端,linux下用clear, windows下用cls
os_type = sys.platform
print(os_type)
if os_type==”linux” or os_type==”linux2”:
cmd=”clear”
else:
cmd=”cls”
sys.path
sys.path是所有库所在的环境列表,包含了python在调用的所有的库(module)所在的环境。
这个环境有什么用呢?
在执行import module_name的时候
python会在sys.path所在的所有目录中进行搜索这个module_name,找到后进行调用
sys.path
大家以后写好的模块就可以放到上面的某一个目录下,便可以正确搜索到了。当然大家也可以添加自己的模块路径。sys.path.append(“my special module path”) .
sys.path 包含输入模块的目录名列表。sys.path的第一个字符串一定是当前py文件所在的目录,这表明当前目录也是sys.path 的一部分,所以你可以直接将调用当前py文件所在目录下的所有模块,其他的与PYTHONPATH 环境变量是相同的。否则,你得把你的模块放在sys.path所列的目录之一。
sys.modules
如果说sys.path 包含了库的所有的环境,sys.modules 则是看现在py文件中调用的所有的库的详细信息。sys.path 是一个字典,它的key是库的名字,而value则是库所要用的文件的路径
import sys
import numpy
print(sys.modules)
可以看出上面在调用sys 和numpy 后,sys.modules 显示了关于他们的详细信息,‘sys’ 和 ‘builtins’ 都是来自python自带的库。而后面一堆关于numpy文件的调用则是来自于anacondas3中的扩展包中的。
sys.stdin,sys.stdout,sys.stderr
stdin , stdout , 以及stderr 变量包含与标准I/O 流对应的流对象。它们可以更好地控制输入和输出的位置。
sys.stdin
sys.stdin 是标准化输入的方法,它接受从键盘中输入的字符串,
最常用的函数和读取文件的函数很像,sys.stdin.readline() 和sys.stdin.readlines() (等同于f.readline() , f.readlines() )
sys.stdin.readline() 用的比较少,其效果和input() 函数完全一致
import sys
print('Please input your name: ')
name = sys.stdin.readline()
print('Hello ', name)
Plase input your name:
Zhang
Hello Zhang
name = input('Please input your name: ')
print('Hello ', name)
Plase input your name: Zhang
Hello Zhang
使用sys.stdin.readline() 可以实现从键盘的标准输入,其中默认输入的格式是字符串,如果是int,float类型则需要强制转换。
sys.stdin.readline() 和input() 有两个不同点
我们先来看例子中发现不同点
name1 = input('Please input your name (input()): ')
print('Hello ', name1)
print('Please input your name (sys.stdin.readline()): ')
name2 = sys.stdin.readline()
print('Hello ', name2)
print('结果细节比较')
li = [name1, name2]
print(li)
-
输入时不同 input() 输入时紧接着输入,sys.stdin.readline() 输入是另起一行,但是这点区别其实不大,只要name = input(‘Please input your name: \n’)就可以完全达到上面的效果 -
输出不同 input() 输出后面就是’‘用户输入的内容’’,sys.stdin.readline() 输出是’‘用户输入的内容\n’’,也就是会自带个换行符
但本质上来说sys.stdin.readline() 的用法和input()的效果一致,没什么特殊用处,所以其完全可以被input()所替代
相比来说,sys.stdin.readlines() 更强大,它可以做到输入多行
除非用户输入ctrl+z 后再按回车确定打断
import sys
print('终端输入')
print('please input name1')
name1 = sys.stdin.readline()
print('please input name2')
name2 = sys.stdin.readline()
print('please input other names, ctrl+z+enter to stop')
names = sys.stdin.readlines()
print('输出')
print(name1)
print(name2)
print(f'names: {names}')
我们先来看结果
我们可以看到输出时sys.stdin.readline() 就和input()的作用一样
但是注意sys.stdin.readline() 的输出之间是空了一行的这是因为本身sys.stdin.readline() 的输出会自带一个换行符’\n’,再加上print(‘…’)最后也会自动在结果中加上一个换行符’\n’,所以总体来说会在中间空一行。
sys.stdin.readlines() 会一次读取多行输入,除非用户输入ctrl+z 后打断表示用户已经停止了输入,否则所有的回车都会默认是换行,就算一行不输入直接按回车不会终止输入。 最后的输出是用户在输入过程中所有内容的内容列表,其中列表中每一个元素对应了用户输入的每一行的内容
本质上sys.stdin.readline() 就对应了读取文件的f.readline() 的,都是每次读取一行(并且会包含每一行的换行符)。
sys.stdin.readlines() 就对应了读取文件的f.readlines() 的,都是每次读取文件之后的所有内容并形成内容列表(并且列表中每一个元素都会包含每一行的换行符)。
它们唯一不同的是,f.readline() 和f.readlines() 的读取对象是文件,sys.stdin.readline() 和sys.stdin.readlines() 的读取对象是终端输入罢了。
sys.stdin.readlines() 在有些网站的笔试中非常重要(如牛客等),如果要获取行数未知的输入,input()几次就成了问题(因为input()一次就是一行罢了),而直接用sys.stdin.readlines() 可以获取一次的所有多行输入(并不需要知道有多少行),后续得到内容列表后,使用len() 和索引就能正常的操作了。 不过注意内容列表每一个元素最后都带有’\n’换行符,除去的话要配合使用strip()。
即
input_ = [line.strip() for line in sys.stdin.readlines()]
sys.stdout
sys.stdout 是将所有print中的结果重新定向输出到指定文件
import sys
print(1)
sys.stdout = open('log', 'a')
print('the error message is written to errlog')
print(2)
print(3)
执行sys.stdout = open('log', 'a') 后,之后print打印信息不会在屏幕上显示,而是会写到log文件中
结果:
可以看出执行sys.stdout = open('log', 'a') 之前第2行的print(1) 输出到了终端
执行sys.stdout = open('log', 'a') 之后所有的内容都写入了log文件
区别于不使用sys.stdout ,直接调用file参数将指定内容写入日志
temp = open('log', 'a')
print(1)
print('cool,you write your first log', file=temp)
print(2)
print(3)
结果
说明只有指定file参数的print写入了log中
而其他的1,2,3都输入到了终端
这种的应用场景是只用记录特定print的到log日志中 区别于sys.stdout ,它会将执行后所有的print都写入log日志中
补充知识点:
注意一般open后面的参数我们只跟’w’和’r’,那这里为什么是’a’呢
实际上**'a’表示追加**
a 以追加模式打开 (从 EOF 开始, 必要时创建新文件,即当没有文件时创建新文件)
因为log日志一般都会记录所有的运行结果,不会因为第二次运行就覆盖了第一次运行的结果
sys.stderr
sys.stderr是将标准错误信息重定向输出到错误文件中
运行代码后错误信息不会在屏幕上显示,会写入到errlog文件中
import sys
sys.stderr = open('errlog', 'a')
wrong
上面的wrong是我未定义的参数,这是我故意写的错误
执行后结果
发现执行sys.stderr = open('errlog', 'a') 后续程序所有的报错信息都将写入errlog文件中,由此就可以记录报错日志
扩展用法
import sys
sys.stderr = open('errlog', 'a')
temp = sys.stderr
print('the error message is written to errlog', file=temp)
print(1)
wrong
第4行的print的信息和第6行的报错信息都写入了errlog文件中
第5行的print信息打印到了终端
从上述例子可以看出sys.stdout 和sys.stderr 还是有本质区别的
sys.stdout 专门负责print中的输出:
只要执行sys.stdout = open('log', 'a') 之后所有的print内容都写入了log文件
sys.stderr 专门负责err中的输出:
只要执行sys.stderr = open('errlog', 'a') 之后所有的报错内容都写入了errlog文件,而不会影响print的信息
|