1.os模块
os表示操作系统
该模块主要处理与操作系统相关的操作,最常用的是文件操作:1.打开 2.读取 3.写入 4.删除 5.复制 6.重命名
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.curdir 返回当前目录: ('.') os.pardir 获取当前目录的父目录字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.sep 输出操作系统特定的路径分隔符,win下为"\",Linux下为"/" os.linesep 输出当前平台使用的行终止符,win下为" ",Linux下为" " os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为: os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix' os.system("bash command") 运行shell命令,直接显示 os.environ 获取系统环境变量 os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.path.isabs(path) 如果path是绝对路径,返回True os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 os.path.getsize(path) 返回path的大小
在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。 >>> os.path.normcase('c:/windows\system32\') 'c:\windows\system32\' 规范化路径,如..和/ >>> os.path.normpath('c://windows\System32\../Temp/') 'c:\windows\Temp' >>> a='/Users/jieli/test1/\a1/\\aa.py/../..' >>> print(os.path.normpath(a)) /Users/jieli/test1
什么时候会用到os模块?
当需要操作文件及文件夹的时候,重点放在对文件的增删改查。
2.subprocess模块
subprocess翻译为子进程,进程指的是正在运行的程序,子进程是由另一个正在运行程序启动的程序,例如:qq聊天,点击了一个链接,打开了浏览器,那么浏览器称之为qq的子进程。
为什么要使用子进程?
当我们有一个任务需要处理,而自己的程序无法处理,所以需要开启另外一个程序。
#1.例如想要在python中获取当前系统所有的进程信息,可以调用os模块的system的方法 import os os.system("tasklist")
System Idle Process 0 Services 0 4 K System 4 Services 0 5,412 K smss.exe 400 Services 0 1,176 K csrss.exe 616 Services 0 4,676 K wininit.exe 756 Services 0 5,804 K services.exe 868 Services 0 7,432 K lsass.exe 888 Services 0 15,028 K svchost.exe 984 Services 0 20,480 K svchost.exe 344 Services 0 10,120 K svchost.exe 1004 Services 0 20,488 K svchost.exe 1048 Services 0 40,540 K svchost.exe 1076 Services 0 25,424 K WUDFHost.exe 1180 Services 0 34,488 K QQPCRTP.exe 1364 Services 0 26,784 K svchost.exe 1420 Services 0 31,472 K svchost.exe 1716 Services 0 26,972 K svchost.exe 1892 Services 0 9,792 K svchost.exe 1980 Services 0 19,540 K svchost.exe 2000 Services 0 11,588 K svchost.exe 1440 Services 0 15,968 K spoolsv.exe 1848 Services 0 14,676 K AlibabaProtect.exe 2284 Services 0 14,316 K dasHost.exe 2332 Services 0 18,220 K svchost.exe 2456 Services 0 304 K GATESRV.exe 2536 Services 0 840 K wlanext.exe 2544 Services 0 7,024 K PnkBstrB.exe 2568 Services 0 6,528 K QQProtect.exe 2628 Services 0 3,608 K PnkBstrA.exe 2636 Services 0 6,356 K conhost.exe 2656 Services 0 5,124 K vmnetdhcp.exe 2668 Services 0 10,992 K pcas.exe 2724 Services 0 1,056 K svchost.exe 2760 Services 0 16,492 K OfficeUpdate.exe 2800 Services 0 3,276 K SearchIndexer.exe 2808 Services 0 49,448 K svchost.exe 2816 Services 0 17,448 K vmnat.exe 2856 Services 0 7,076 K vmware-usbarbitrator64.ex 2888 Services 0 256 K wwbizsrv.exe 2896 Services 0 2,540 K svchost.exe 3272 Services 0 7,932 K svchost.exe 484 Services 0 10,592 K csrss.exe 9272 Console 2 43,060 K winlogon.exe 4668 Console 2 10,232 K dwm.exe 584 Console 2 103,960 K MasterHelper.exe 10028 Console 2 2,424 K ProcHelper64.exe 8616 Console 2 304 K svchost.exe 6956 Console 2 20,468 K sihost.exe 7732 Console 2 22,316 K taskhostw.exe 8832 Console 2 22,136 K ChsIME.exe 4024 Console 2 7,956 K RuntimeBroker.exe 10068 Console 2 20,668 K explorer.exe 2928 Console 2 225,192 K QQPCTray.exe 6124 Console 2 60,660 K ShellExperienceHost.exe 6192 Console 2 84,340 K SearchUI.exe 9528 Console 2 119,788 K DriveTheLife.exe 6504 Console 2 5,288 K QQPCNetFlow.exe 7236 Console 2 7,304 K QQPCRealTimeSpeedup.exe 8228 Console 2 51,328 K UpdateSoftTip.exe 9036 Console 2 5,080 K SoftMgrUpdateNotify.exe 9856 Console 2 660 K SogouCloud.exe 4672 Console 2 7,040 K DispcapHelper.exe 9552 Console 2 488 K pycharm.exe 3928 Console 2 436,012 K fsnotifier.exe 5208 Console 2 356 K conhost.exe 2240 Console 2 9,328 K QMDeskTopGC.exe 5868 Console 2 2,572 K QQ.exe 4700 Console 2 142,108 K TXPlatform.exe 3996 Console 2 96 K PDZipTool.exe 5816 Console 2 10,132 K ApplicationFrameHost.exe 1900 Console 2 33,608 K wpscloudsvr.exe 7524 Console 2 26,568 K wpscenter.exe 7956 Console 2 12,352 K WmiPrvSE.exe 7908 Services 0 13,348 K SogouImeBroker.exe 4660 Console 2 216 K chrome.exe 8600 Console 2 147,556 K chrome.exe 724 Console 2 1,096 K chrome.exe 1784 Console 2 760 K chrome.exe 7628 Console 2 4,980 K chrome.exe 7160 Console 2 6,600 K chrome.exe 4512 Console 2 7,688 K chrome.exe 8044 Console 2 57,600 K SystemSettingsBroker.exe 7408 Console 2 20,704 K StudentMain.exe 9432 Console 2 7,460 K chrome.exe 5100 Console 2 52,748 K chrome.exe 11220 Console 2 51,004 K chrome.exe 10812 Console 2 6,576 K chrome.exe 9536 Console 2 7,120 K chrome.exe 7332 Console 2 69,372 K cloudmusic.exe 6420 Console 2 40,900 K cloudmusic.exe 6808 Console 2 34,800 K cloudmusic.exe 11116 Console 2 33,428 K audiodg.exe 4300 Services 0 24,808 K chrome.exe 11196 Console 2 4,884 K WUDFHost.exe 9596 Services 0 8,300 K QMUsbGuard.exe 10436 Console 2 10,812 K wpscenter.exe 7712 Console 2 2,460 K SearchProtocolHost.exe 4688 Services 0 11,360 K SearchFilterHost.exe 7188 Services 0 8,584 K SGTool.exe 10976 Console 2 18,100 K python.exe 7872 Console 2 30,584 K conhost.exe 10264 Console 2 9,604 K cmd.exe 11468 Console 2 2,792 K tasklist.exe 11940 Console 2 7,932 K
os.system和subprocess的区别
os.system可以执行系统指令,命令操作系统打开一个应用程序,然而os.system在执行命令的时候直接把结果返回到了控制台,如果我们需要获取执行的结果,os,system无能为力。
subprocess不仅可以启动子进程,还能与子进程。
import subprocess p1 = subprocess.Popen("dir",shell=True,stdout=subprocess.PIPE) #dir表示的是一个需要执行的命令语句,必须加上双引号。 #shell表示dir是一个命令 #stdout 指定输出管道,相当于生活中的水管 水可以通过管道 从一个地方流到另一个地方 # 在程序中 数据相当于水 管道的作用,就从一个进程中把数据传输到另一个进程。
上面代码是 启动了一个dir子进程 并将结果输出到指定管道。
小练习:
1.启动一个tasklist子进程 指定输出结果到管道中
2.启动一个findstr的子进程 将p1进程的结果作为p2进程输入
# 1.启动一个tasklist子进程 指定输出结果到管道中 # # 2.启动一个findstr的子进程 将p1进程的结果作为p2进程输入,findstr单独显示cmd.exe的详细信息 import subprocess p1=subprocess.Popen('tasklist',shell=True,stdout=subprocess.PIPE) p2=subprocess.Popen('findstr cmd',shell=True,stdin=p1.stdout,stdout=subprocess.PIPE,stderr=subprocess.PIPE) print(p2.stdout.read()) print(p2.stderr.read().decode('GBK')) #当p2这个子进程出错时,错误信息会在错误管道stderr中被获取
3.configparser
configparser模块的基本操作
"""
configerparser模块是用来写配置文件的,首先需要了解配置文件xxx.clg的内容是怎么样的。 如下:在一个cfg文件中的内容格式如下: -------------------------------------------- [mysql] #代表分区 username = jack 分区中的名称(变量) password = 123 lock = true [django] . . . -------------------------------------------- 一个cfg中可以有多个分区,一个分区也可以有多个名称(变量) """ #configparser基本操作 import configparser cfg=configparser.ConfigParser() # 创建一个配置文件解析器 cfg.read('my_config.cfg',encoding='utf-8') # 读取名为my_config.cfg的配置文件 print(cfg.sections()) #获取cfg中的分区,返回值是一个列表
>>>:['mysql', 'json'] # 获取某个分区下的某个选项 第一个参数分区名 第二个选项名称 username = cfg.get("mysql","username") print(username) print(type(username))
>>>:
egon
<class 'str'>
# 以下三个函数是帮你封装了 类型转换 # cfg.getfloat() password = cfg.getfloat("mysql","password") print(password) print(type(password))
>>>:
123456.0
<class 'float'>
# cfg.getint() password = cfg.getint("mysql","password") print(password) print(type(password))
>>>:
123456
<class 'int'>
# cfg.getboolean() lock=cfg.getboolean('mysql','lock') print(lock) print(type(lock))
>>>:
False
<class 'bool'>
configparser模块的增删改查
import configparser cfg = configparser.ConfigParser() cfg.read("my_config.cfg",encoding="utf-8") #修改 # 将mysql分区下的lock改为True cfg.set('mysql','lock','True') #由于此时还是在内存中修改,所以需要把修改后的cfg文件覆盖原来的cfg文件 with open('my_config.cfg','wt',encoding='utf-8')as f: cfg.write(f) #------------------------------------------------------------------- #在mysql分区中添加新的分区,也需要写入文件覆盖 cfg.add_section('新分区') #如果重复写入,会报错,只要配置文件中已经存在那就不能再写入 #在mysql分区中添加新的选项 port 值为3306,也需要写入文件覆盖 cfg.set('mysql','port','3306') with open('my_config.cfg','wt',encoding='utf-8')as f: cfg.write(f) #------------------------------------------------------------------- #删除一个分区 cfg.remove_section('新分区') # 删除某个分区的选项 cfg.remove_option('mysql','port') with open('my_config.cfg','wt',encoding='utf-8')as f: cfg.write(f) #------------------------------------------------------------------- # 判断是否存在某个分区 print(cfg.has_section('新分区')) # 判断是否存在某个选项 print(cfg.has_option('mysql','username'))
注意:
不能出现重复的分区名
同一个分区下不能有相同的选项名
值可以是任何类型 且字符串不需要加引号
4.shutil模块
shutil模块介绍
shutil模块时一个工具包,封装了文件高级操作,让你操作起来更方便,其功能与os有些重叠,但是os只能处理文件存在,路径存在等问题,无法直接完成copy等操作,而shutil则有这类操作,并且还提供了压缩与解压操作。
shutil拷贝操作
import shutil #shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中 shutil.copyfileobj(open('a.json','r'), open('new.json', 'w')) #被拷贝文件必须存在 #shutil.copyfile(src, dst) 拷贝文件 shutil.copyfile('a.json', 'a1.json') #目标文件无需存在 # shutil.copystat(src, dst) #仅拷贝状态的信息,包括:mode#,bits, atime, mtime, flags shutil.copystat('f1.log', 'f2.log') # 目标文件必须存在 # shutil.copy(src, dst) # 拷贝文件和权限 shutil.copy('f1.log', 'f2.log') # hutil.copy2(src, dst) 拷贝文件和状态信息 shutil.copy2('f1.log', 'f2.log') # shutil.ignore_patterns(*patterns) # shutil.copytree(src, dst, symlinks=False, ignore=None) 递归的去拷贝文件夹 shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) # 目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除 #shutil.rmtree(path[, ignore_errors[, onerror]]) 递归的去删除文件 shutil.rmtree('folder1') # shutil.move(src, dst) 递归的去移动文件,它类似mv命令,其实就是重命名。 shutil.move('folder1', 'folder3')
shutil压缩解压操作
import shutil # 压缩 将 D:学习old_boy_studyhomework草稿 下的文件打包放置当前程序目录,命名为1.py.zip shutil.make_archive("1.py", "zip", r"D:学习old_boy_studyhomework草稿" ) #解压 shutil.unpack_archive("1.py.zip", r"D:学习old_boy_studyhomework草稿这是解压的文件", 'zip')
5.xml模块
什么是XML 全称叫做可扩展标记语言 是一种定义电子文档结构和描述的语言,可以用来标记数据、定义数据类型 用户可以对自己的标记语言进行定义和扩展,由W3C(万维网标准组织)推出,几乎所有的编程语言都支持该格式 标记翻译为标签,标签指的是某种特殊符号,简单的是XML就是用标签来定义文档结构 XML文档格式 来看一个例子: <person name="jack">hello i am a person</person> 一个完整的标签分为三个部分 标签名(tagname): person 属性(attribute): name 值为jack 文本(text): hello i am a person 属性和文本都是可选的,所以你可以这样来定义一个空标签 <person></person> 其他格式要求: 一、任何的起始标签都必须有一个结束标签。 二、可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如。XML解析器会将其翻译成。 三、标签必须按顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。 四、所有的属性都必须有值。 五、所有的特性都必须在值的周围加上双引号。 六、最外层必须有且只能有一个标签,称为根标签 与JSON的对比 json是JavaScript语言的对象表示法,其仅支持js中的数据类型,(虽然大多数情况下是足够使用的),之所以出现是因为在开发中,通常都需要后台向前台传输数据,那自然是要传输前台能看懂的数据格式,json就是这样一种数据格式,可以轻松的被js语言解析,使用场景多为前后台交互 而xml支持的数据类型理论上是不受限制的,因为可以完全自定义标签的结构和含义,使用场景也非常广泛,不局限于前后台的数据交互,在一些语言中还经常作为配置文件来使用 另外,HTML 看起来与XML非常的类似,的确,HTML也属于XML 如果仅仅将XML用做数据交换格式的话,远不如json来的简单,由于出现时间的关系,有很多早期项目都是使用XML来完成的 使用XML模块解析 准备数据 <?xml version="1.0"?> <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> <rank updated="yes">69</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data> 解析XML import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() print(root.tag) #遍历xml文档 for child in root: print('========>',child.tag,child.attrib,child.attrib['name']) for i in child: print(i.tag,i.attrib,i.text) #只遍历year 节点 for node in root.iter('year'): print(node.tag,node.text) #--------------------------------------- import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() #修改 for node in root.iter('year'): new_year=int(node.text)+1 node.text=str(new_year) node.set('updated','yes') node.set('version','1.0') tree.write('test.xml') #删除node for country in root.findall('country'): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write('output.xml') 1.三个用于查找标签函数 iter("标签名") #全文查找 find("标签名") #查找子节点匹配的第一个 findall("标签名") #查找字节点匹配的所有 2.访问标签的内容 element.tag 获取标签名 element.attrib 获取属性 element.text 获取文本 3.修改文档内容 elment.tag = "标签名" element.text = "文本" element.set("属性名","属性值") 4.删除节点 root.remove(标签对象) 5.添加子标签 #创建标签对象 year2=ET.Element('year2') # 指定名称 year2.text='新年' year2.attrib={'update':'yes'} #添加 country.append(year2) #往country节点下添加子节点 删除添加修改后都需要调用write写入到文件 tree.write("文件名"),#注意文档对象才能执行写入操作 代码生成XML文档(了解) import xml.etree.ElementTree as ET new_xml = ET.Element("namelist") name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"}) age = ET.SubElement(name,"age",attrib={"checked":"no"}) sex = ET.SubElement(name,"sex") sex.text = 'man' name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"}) age = ET.SubElement(name2,"age") age.text = '19' et = ET.ElementTree(new_xml) #生成文档对象 et.write("test.xml", encoding="utf-8",xml_declaration=True) ET.dump(new_xml) #打印生成的格式 总结,xml的解析比起json而言非常复杂 因为其扩展性远比json高,在java中常作为配置文件,当你在前后台进行数据交互时,优先是用json格式 疑惑:文本也可以作为属性,属性也可以作为文本,?到底如何选择?, XML不仅仅可以定义数据结构还可以定义数据的显示样式,想想HTML!