一、random随机数模块
使用随机数模块需要导入随机数模块import random
1.random.random()
生成[0,1)之间的随机小数
2.random.randint(a,b)
生成[a,b]之间的随机整数
3.random.randrange(a,b[,c])
生成[a,b)之间的随机整数,要求a<b,如果有参数c则步长为c
4.random.uniform(a,b)
生成[a,b]之间的随机小数,a和b之间没有大小要求
5.random.choice(序列)
在序列中随机选取一个元素,参数为一个序列,可以为字符串、列表或元组
6.random.sample(序列,n)
在序列中随机选取n个,第一个参数为一个序列,第二个参数表示从序列中选取的个数
7.random.shuffle(l)
打乱列表的元素顺序,参数为一个列表
random.choice(序列)和random.sample(序列,n)都不修改原序列,返回随机选取出来的值
random.shuffle(l)会直接修改列表,返回值为None,如果要查看修改后的列表不能直接打印即不能print(random.shuffle(l)),而是直接打印列表
import random print(random.random()) print(random.randint(1,5)) print(random.randrange(2,26[,3])) print(random.choice([1,'hi',[1,2]])) print(random.sample([1,'hi',[1,2]],2)) print(random.uniform(5,3.6)) a=[1,'a',2,3,'b'] random.shuffle(a) print(a)
二、shutil文件操作模块
参考https://www.cnblogs.com/xiangsikai/p/7787101.html
os模块提供了对目录或者文件的新建、删除、查看文件属性,还提供了对文件以及目录的路径操作,比如说绝对路径、父目录…… 但是文件的操作还应该包含移动、复制、打包、压缩、解压等操作,这些功能os模块没有提供。而shutil模块则是对文件操作的补充,即移动、复制、打包、压缩、解压等操作,需导入模块import shutil。
1.文件操作
①只拷贝文件内容:shutil.copyfileobj(fsrc, fdst[, length]),相当于用原文件的内容覆盖目标文件的内容
f1=open('a.ini','r') f2=open('b.ini','w') shutil.copyfileobj(f1,f2)
原文件要以读的模式打开,目标文件要以写的模式打开
②拷贝文件:shutil.copyfile(src, dst),相当于创建一个空的目标文件,再把原文件内容覆盖到目标文件
shutil.copyfile('a.ini','b.ini')
copyfile不需要打开文件。
③拷贝权限:shutil.copymode(src, dst)
shutil.copymode('a.ini','b.ini')
要求目标文件存在。
④拷贝状态信息:shutil.copystat(src, dst),包括创建、访问和修改时间等
shutil.copystat('a.ini','b.ini')
⑤拷贝文件和权限:shutil.copy(src, dst),即先copyfile再copymode
shutil.copy('a.ini','b.ini')
⑥拷贝文件和状态:shutil.copy2(src, dst),即先copyfile再copystat
shutil.copy2('a.ini','b.ini')
⑦移动文件:shutil.move(源文件,指定路径),相当于复制到一个指定路径下并重命名
shutil.move('a.ini','/test/b.ini')
2.目录操作
①shutil.copytree(源目录,目标目录),递归复制目录及目录下的文件,状态信息也一并复制了
shutil.copytree('test/','test_copy/') shutil.copytree('test/','test_copy/',shutil.ignore_patterns('*.txt','tmp*'))
copytree加参数shutil.ignore_patterns ('模式')表示忽略符合该条件的文件,即选择性复制
②shutil.rmtree(目标目录):递归删除目录及目录下的文件
shutil.rmtree('test/')
3.打包与压缩
①make_archive(base_name, format, root_dir=' ', base_dir=None, verbose=0,dry_run=0, owner=None, group=None, logger=None) 打包、压缩
整个语句的返回值为压缩或打包后的文件的路径+文件名称(文件名称带有相应格式的后缀)
base_name:压缩、打包后的文件名称,无路径则表示当前路径,如果要保存至指定路径则需要指定路径,此处的文件名称不需加格式后缀,打包或压缩完成后会自动加上
format:压缩或打包的格式,有tar、zip、bztar、gztar等
root_dir:打包时切换到的根路径。也就是说开始打包前,会先执行路径切换,切换到root_dir所指定的路径,默认值为当前路径
base_dir:开始打包的路径。也就是说对base_dir所指定的路径进行打包,默认值为 root_dir
owner和group:创建tar包时使用,默认为用户当前的用户和组
logger: 用于记录日志,通常是logging.Logger对象,可省略
#当前/root目录下,要将/root/tmp/test/目录打包并以gztar格式进行压缩,压缩后名称为test_bak,放置在test相同目录下 import shutil re=shutil.make_archive('/root/tmp/test_bak','gztar','/root/tmp/test/') print(re) #执行结果 /root/tmp/test_bak.tar.gz #上述语句执行前 ls /root/tmp/test/test|grep test* test #上述语句执行后 ls /root/tmp/test/test|grep test* test test.tar.gz
②shutil.unpack_archive(file_name,unpack_path) 解压缩
file_name:需要解包的文件,需要写上文件后缀名
unpack_path :解包后文件存放的位置
(参考 https://www.jb51.net/article/135049.htm 感谢)
三、zipfile、tarfile的用法
先占个位置,后续再实际操作和补充
参考 https://www.cnblogs.com/MnCu8261/p/5494807.html
四、json、pickle、shelve数据类型转换模块
1.json模块
用于文件处理时其他数据类型与json字符串之间转换。在将其他数据类型转换为json字符串时(dump方法),首先将前者内部所有的单引号变为双引号,再整体加上引号(单或双)转换为json字符串;再使用时再将json字符串还原为本来的数据(load方法)。
json有两对方法json.dumps()和json.loads(),json.dump()和json.load()。
但是dump和load不是必须同时使用,只要字符串满足json规则(引号全部为双引号),可以直接使用load读取。
(在html前端,JSON.stringify(v)可将其他格式数据转化为json字符串,JSON.parse(str)可将json字符串还原为原格式)
import json l=[1,'hello',{'name':'Alex'}] with open('new.txt','w') as f: l_str=json.dumps(l) #将列表l转换为js字符串 f.write(l_str) #将字符串写入文本 print(l_str, type(l_str)) #输出[1,"hello", {"name": "Alex"}] <class 'str'>,可以看见原列表中所有的单引号全部变成了双引号,并且整体类型为字符串 with open('new.txt','r') as f: l=f.read() print(l,json.loads(l),type(json.loads(l))) #输出[1,"hello", {"name": "Alex"}] [1,'hello', {'name': 'Alex'}] <class 'list'>
上述最后一行可以看见,由于写入时为json字符串,直接读取时也为json字符串,即引号全部为双引号,而json.loads()是将dump处理过的字符串变成了原来的列表,并且处理过的双引号全部变回了单引号。
在上述文件中,转换和写操作l_str=json.dumps(l)和f.write(l_str)可以用一步json.dump(l,f)代替
在上述文件中,读和转换操作l=f.read()和json.loads(l)可以用一步json.load(f)代替
2.pickle模块
pickle的用法类似于json,不同的是json是将其它数据类型与字符串进行转换,而pickle是将其它数据类型与字节进行转换。由于是与字节进行转换,所以打开文件时需要以b的方式。
通过pickle把变量从内存中变成可存储或可传输的过程称之为序列化,反之,把变量内容从序列化的对象重新读取到内存里称之为反序列化。
import pickle l=[1,'hello'] with open('c.txt','wb') as f: pickle.dump(l,f) with open('c.txt','rb') as f: print(pickle.load(f))
3.shelve模块
shelve是通过键值对,即字典的形式去存储数据的,键必须为字符串,值可以为任何python数据类型。
shelve只有open和close方法,open的时候参数为文件名,执行之后会生成后缀分别为dat、bak、dir的三个文件。
import shelve s=shelve.open('test') #参数为文件名,执行之后会生成test.dat、test.bak、test.dir,此时s相当于一个空字典 s['one']=12 #通过字典的方式给赋值 s['two']={'name':'Alice','age':19} s['three']=[1,'hello'] s.close() s=shelve.open('test') print(s['one']) #输出12 print(s['two']['age']) #输出19 s['one']=20 #直接通过字典的方式修改值 s.close()
五、hashlib加密模块
hashlib模块对文件或字符串进行加密处理,加密过程不可逆。常用方法有md5()和sha256(),其余还有sha1()、sha224()、sha384()、sha512()等方法。
以md5()的使用为例讲解用法
import hashlib h=hashlib.md5() h.update('admin'.encode('utf8')) #将admin通过utf8编码为字节,再进行加密 print(h.hexdigest()) #获取加密后的字符串
上述单纯的加密算法很容易被暴力破解,为防止此情况发生,可在加密时加入“杂质”,即在hashlib.md5()中加入参数作为杂质
import hashlib h=hashlib.md5('hello'.encode('utf8')) #加入杂质hello h.update('admin'.encode('utf8'))
print(h.hexdigest())
需要注意的是,下面这个例子,先对admin加密,再对root加密,最后的结果实际是对admin和root的拼接、即adminroot做的加密
import hashlib h=hashlib.md5() h.update('admin'.encode('utf8')) print(h.hexdigest()) h.update('root'.encode('utf8')) print(h.hexdigest()) #4b3626865dc6d5cfe1c60b855e68634a
可进行验证
import hashlib h=hashlib.md5() h.update('root'.encode('utf8')) print(h.hexdigest()) #63a9f0ea7bb98050796b649e85481845
import hashlib h=hashlib.md5() h.update('adminroot'.encode('utf8')) print(h.hexdigest()) #4b3626865dc6d5cfe1c60b855e68634a
六、logging日志模块
logging模块中日志分为五个级别,分别是debug、info、warning、error、critical,默认级别为warning。
通过logging.basicConfig设置日志的显示参数,再通过logging.debug等方法输出日志,这种方法要么只能输出日志到屏幕,要么只能输出日志到一个文件中,无法同时输出到屏幕和文件。
import logging logging.basicConfig( level=logging.WARNING, #设置级别为WARN级别,默认就为WARNING级别 filename='log.log', #设置日志输出到脚本所在路径下的log.log文件,默认输出到当前屏幕 filemode='w', #默认为写模式,默认为追加模式 format='%(asctime)s %(filename)s[%(lineno)d] %(message)s' #日志格式 ) logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') #输出文件如下 #2018-11-21 10:22:14,183 log.py[10] warning message #2018-11-21 10:22:14,183 log.py[11] error message #2018-11-21 10:22:14,184 log.py[12] critical message
以上,在logging.basicConfig的format中可设置日志显示的各种参数
%(asctime)s:以字符串形式显示当前时间,默认格式为2018-11-20 21:06:04,862
%(name)s:登录用户
%(pathname)s:调用日志输出函数的模块的完整路径
%(filename)s:调用日志输出函数的模块的文件名
%(module)s:调用日志输出函数的模块名
%(funcName)s:调用日志输出函数的函数名
%(lineno)d:调用日志输出函数的语句所在代码行
%(process)d:进程id
%(thread)d:线程id
%(threadName)s:线程名
%(levelno)s:数字形式的日志级别
%(levelname)s:文本形式的日志级别
%(created)f:当前时间,用unix标准的表示时间的浮点数表示
%(relativeCreated)d:输出日志信息时的、自logger创建以来的毫秒数
通过logging.getLogger()方法生成对象并设置各种参数,再调用对象的debug等方法显示日志
def logger(): #定义文件 logger=logging.getLogger() #创建一个logger对象,默认为根用户 fh=logging.FileHandler('test_log') #创建向文件输出日志的对象,参数为目标文件的名称 sh=logging.StreamHandler() #创建向屏幕输出日志的对象 fm=logging.Formatter('%(asctime)s %(name)s %(message)s') #创建格式对象 fh.setFormatter(fm) #设置向文件输出日志的对象的格式 sh.setFormatter(fm) #设置向屏幕输出日志的对象的格式 logger.addHandler(fh) #logger对象增加向文件输出日志的功能 logger.addHandler(sh) #logger对象增加向屏幕输出日志的功能 logger.setLevel('DEBUG') #设置logger对象的日志显示级别 return logger logger = logger() logger.debug('debug message') logger.info('info message') logger.warning('warning message') logger.error('error message') logger.critical('critical message')
logger=logging.getLogger()默认创建的是根用户的对象,如果加参数例如‘test’,表示创建的是根用户下的test用户,如果再要创建test下的子用户,需加通过.加参数例如'test.son',且如果参数相同,则创建的多个对象都是同一个对象,对其设置的格式、日志等级等,都以最后一个为准。
如果创建根用户对象和根用户的子对象,或者一个对象和它的子对象,则子对象的日志会输出两遍,即子对象有几层父对象,它的日志就会输出几遍。
logger=logging.getLogger('phh') logger1 = logging.getLogger('phh.girl') fh=logging.FileHandler('test_log') sh=logging.StreamHandler() fm=logging.Formatter('%(asctime)s %(name)s %(message)s') fh.setFormatter(fm) sh.setFormatter(fm) logger.addHandler(fh) logger.addHandler(sh) logger1.addHandler(sh) logger.setLevel('WARNING') logger1.setLevel('ERROR') logger.debug('debug message') logger.info('info message') logger.warning('warning message') logger.error('error message') logger.critical('critical message') logger1.debug('1 debug message') logger1.info('1 info message') logger1.warning('1 warning message') logger1.error('1 error message') logger1.critical('1 critical message') #输出内容如下 # 2018-11-21 21:03:51,999 phh warning message # 2018-11-21 21:03:51,999 phh error message # 2018-11-21 21:03:51,999 phh critical message # 2018-11-21 21:03:52,000 phh.girl 1 error message # 2018-11-21 21:03:52,000 phh.girl 1 error message # 2018-11-21 21:03:52,000 phh.girl 1 critical message # 2018-11-21 21:03:52,000 phh.girl 1 critical message
七、paramiko远程登录模块
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作。
如果python服务器对被远程控制机器开启了免密验证,即在python服务器上可通过ssh 用户名@被控制机器ip 登录被远程控制机器而不用输入密码,那么可以获取python服务器的私钥并通过私钥进行连接,如果没有开启免密验证则通过密码进行连接。
1.开启免密验证
#执行命令 import paramiko #获取本机私钥 private_key=paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa') #实例化SSHClient ssh = paramiko.SSHClient() #自动添加策略,保存python服务器的主机名和密钥信息 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #连接被远程控制机器 ssh.connect('被控制机器ip', 端口号, '登录用户名', private_key[,timeout=n]) #打开一个channel并执行命令 stdin, stdout, stderr = ssh.exec_command('command') #打印执行结果 print(stdout.read()) #关闭SSHClient ssh.close()
#上传文件 import paramiko #获取本机私钥 private_key=paramiko.RSAKey.from_private_key_file(/root/.ssh/id_rsa) #获取Transport实例 t=paramiko.Transport('被控制机器ip',端口号)) #连接SSH服务端 t.connect('登录用户名',private_key) #获取sftp实例 sftp = paramiko.SFTPClient.from_transport(t) #上传文件 sftp.put('log.log','/tmp/log.log') #关闭sftp连接 t.close() #下载文件 import paramiko #获取本机私钥 private_key=paramiko.RSAKey.from_private_key_file(/root/.ssh/id_rsa) #获取Transport实例 t=paramiko.Transport('被控制机器ip',端口号)) #连接SSH服务端 t.connect('登录用户名',private_key) #获取sftp实例 sftp = paramiko.SFTPClient.from_transport(t) #下载文件 sftp.get('/tmp/log.log', 'log3.log') #关闭sftp连接 t.close()
2.未开启免密验证
#执行命令 import paramiko #实例化SSHClient ssh = paramiko.SSHClient() #自动添加策略,保存python服务器的主机名和密钥信息 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #连接被远程控制机器 ssh.connect('被控制机器ip', 端口号, '登录用户名', '登录密码'[,timeout=n]) #打开一个channel并执行命令 stdin, stdout, stderr = ssh.exec_command('command') #打印执行结果 print(stdout.read()) #关闭SSHClient ssh.close()
#上传文件 import paramiko#获取Transport实例 t=paramiko.Transport('被控制机器ip',端口号)) #连接SSH服务端 t.connect('登录用户名','登录密码') #获取sftp实例 sftp = paramiko.SFTPClient.from_transport(t) #上传文件 sftp.put('log.log','/tmp/log.log') #关闭sftp连接 t.close() #下载文件 import paramiko#获取Transport实例 t=paramiko.Transport('被控制机器ip',端口号)) #连接SSH服务端 t.connect('登录用户名','登录密码') #获取sftp实例 sftp = paramiko.SFTPClient.from_transport(t) #下载文件 sftp.get('/tmp/log.log', 'log3.log') #关闭sftp连接 t.close()
八、subprocess模块
若指定了shell=True,可同时执行多个命令,命令之间用分号隔开。
1.subprocess.run()
执行命令,将结果和命令打印至屏幕。不加shell=True参数,则将命令作为列表传递,添加shell=True参数则直接传递命令。
>>> import subprocess >>> subprocess.run(['ls','-l']) total 16 -rw-r--r-- 1 root root 115 Nov 17 14:36 a.py -rw-r--r-- 1 root root 27 Nov 17 14:23 argv.py drwxr-xr-x 2 root root 4096 Nov 17 19:59 __pycache__ -rw-r--r-- 1 root root 238 Nov 17 19:59 shelve.py CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run('ls -l',shell=True) total 16 -rw-r--r-- 1 root root 115 Nov 17 14:36 a.py -rw-r--r-- 1 root root 27 Nov 17 14:23 argv.py drwxr-xr-x 2 root root 4096 Nov 17 19:59 __pycache__ -rw-r--r-- 1 root root 238 Nov 17 19:59 shelve.py CompletedProcess(args='ls -l', returncode=0)
2.subprocess.call()
执行命令,将结果和状态码打印至屏幕,正确执行则状态码为0否则非0。
>>> res = subprocess.call('ls -l',shell=True) total 16 -rw-r--r-- 1 root root 115 Nov 17 14:36 a.py -rw-r--r-- 1 root root 27 Nov 17 14:23 argv.py drwxr-xr-x 2 root root 4096 Nov 17 19:59 __pycache__ -rw-r--r-- 1 root root 238 Nov 17 19:59 shelve.py >>> res 0 >>> subprocess.call('ls -l',shell=True) total 16 -rw-r--r-- 1 root root 115 Nov 17 14:36 a.py -rw-r--r-- 1 root root 27 Nov 17 14:23 argv.py drwxr-xr-x 2 root root 4096 Nov 17 19:59 __pycache__ -rw-r--r-- 1 root root 238 Nov 17 19:59 shelve.py 0 >>> subprocess.call('la',shell=True) /bin/sh: la: command not found 127
3.subprocess.check_call()
执行命令,正确执行则将结果和状态码打印至屏幕(与call一样),错误则抛出异常。
>>> subprocess.check_call('ls -l',shell=True) total 16 -rw-r--r-- 1 root root 115 Nov 17 14:36 a.py -rw-r--r-- 1 root root 27 Nov 17 14:23 argv.py drwxr-xr-x 2 root root 4096 Nov 17 19:59 __pycache__ -rw-r--r-- 1 root root 238 Nov 17 19:59 shelve.py 0 >>> subprocess.check_call('la',shell=True) /bin/sh: la: command not found Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/python3.7/lib/python3.7/subprocess.py", line 328, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command 'la' returned non-zero exit status 127.
4.subprocess.getstatusoutput()
接收字符串形式的命令,返回一个元组,元组的第一个元素为执行状态码,第二个元素位置为执行结果。
>>> subprocess.getstatusoutput('pwd') (0, '/root/test') >>> a = subprocess.getstatusoutput('ls') >>> a (0, 'a.py argv.py __pycache__ shelve.py')
5.subprocess.getoutput()
接收字符串形式的命令,执行命令并获取返回结果
>>> subprocess.getoutput('ls') 'a.py argv.py __pycache__ shelve.py' >>> a = subprocess.getoutput('pwd') >>> a '/root/test'
6.subprocess.check_output()
执行命令,以字节形式返回结果。
>>> subprocess.check_output("pwd") b'/root/test '
7.subprocess.Popen()
①stdout和stderr,标准输出和标准错误,需要通过read读出,读出的结果为字节。
>>> subprocess.Popen('ls -l',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) <subprocess.Popen object at 0x7fb7b24eb550> >>> res = subprocess.Popen('ls -l',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> res.stdout.read() b'total 16 -rw-r--r-- 1 root root 115 Nov 17 14:36 a.py -rw-r--r-- 1 root root 27 Nov 17 14:23 argv.py drwxr-xr-x 2 root root 4096 Nov 17 19:59 __pycache__ -rw-r--r-- 1 root root 238 Nov 17 19:59 shelve.py ' >>> res = subprocess.Popen('la',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> res.stderr.read() b'/bin/sh: la: command not found ' >>> res.stdout.read() b''
②poll(),检查命令是否执行完成,未执行完成返回None,完成返回0
>>> res = subprocess.Popen('sleep 10;ls -l',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> print(res.poll()) None >>> print(res.poll()) None >>> print(res.poll()) #10s之前结果一直为None,10s之后返回0 0
③wait(),挂起直到命令执行完成,并返回执行状态
>>> res = subprocess.Popen('sleep 10;ls -l',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> res.wait() #等待状态,此时不接收其他命令,10s后返回状态0即执行完毕 0
④terminate(),终止执行
>>> res = subprocess.Popen('sleep 10;ls -l',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> res.terminate() >>> res.stdout.read() b''
⑤pid,当前子shell进程的pid
>>> res = subprocess.Popen('ls -l',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) >>> res.pid 9394
九、configparser生成配置文件模块
1.基本用法
import configparser config = configparser.ConfigParser() #相当于生成了一个空字典config{} config["DEFAULT"] = {'ServerAliveInterval': '45', 'Compression': 'yes', 'CompressionLevel': '9'} #使用字典的方式给config赋值 config['bitbucket.org'] = {} config['bitbucket.org']['User'] = 'hg' config['topsecret.server.com'] = {} topsecret = config['topsecret.server.com'] topsecret['Host Port'] = '50022' # mutates the parser topsecret['ForwardX11'] = 'no' # same here with open('example.ini', 'w') as f: config.write(f) #将删除内容写入文件 #生成文件的内容如下 #[DEFAULT] #serveraliveinterval = 45 #compression = yes #compressionlevel = 9 #[bitbucket.org] #user = hg #[topsecret.server.com] #host port = 50022 #forwardx11 = no
在以块为单位取块的值时,DEFAULT块都会出现。
2.获取块名
通过config.sections()可获取除了DEFAULT之外的块名,返回结果为一个列表
config.read('example.ini') #读取文件 print(config.sections()) #config.sections()返回一个列表['bitbucket.org', 'topsecret.server.com'],包含除了DEFAULT之外的块名,需要事先读取文件 print(config['bitbucket.org']['user']) #使用字典的方式取值 print(config['DEFAULT']['compression'])
3.遍历块
当遍历除了DEFAULT之外的某一个块时,DEFAULT的内容也会被显示
for i in config['bitbucket.org']: print(i) #输出结果如下 # user # serveraliveinterval # compression # compressionlevel
4.获取块的键和值
通过config.options()和config.items()获取块的键和键值对,通过config.get('块名','键')获取键对应的值
print(config.options('bitbucket.org')) print(config.items('bitbucket.org')) print(config.get('bitbucket.org','user')) #输出内容如下 # ['user', 'serveraliveinterval', 'compression', 'compressionlevel'] # [('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('user', 'hg')] # hg
5.增加块
增加块config.add_section('块名')、增加块中的键值对config.set('块名','键','值')
config.read('example.ini') #先读取文件 config.add_section('hello') #增加块hello,已经存在的块会报错 config.set('hello','type','python') #增加块hello的键值对 config.write(open('example.ini','w')) #将增加操作写入文件
6.删除块
删除块config.remove_section('块名')、删除块中的键值对config.remove_option('块名','键')
config.read('example.ini') config.remove_section('bitbucket.org') #删除块 config.remove_option('hello','type') #删除块下面的键值对 config.write(open('example.ini','w'))
十、xml模块
xml是实现不同语言或程序之间数据交换的协议,类似json,比json出现得更早。
如下一个名为xml_test的文件,下面的操作都对这个文件进行
<date>和</date>、<country>和</country>、<year>和</year>等成对出现的为非闭合标签,而<neighbor>是自闭合标签,自闭合标签没有值也没有子标签。
<data> <country name="Liechtenstein"> <rank updated="yes">2</rank> #rank为标签tag,update为标签的属性attribute,yes为属性的值,2为标签的值text <year>2010</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2013</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> <country name="Panama"> <rank updated="yes">69</rank> <year>2013</year> <gdppc>13600</gdppc> <neighbor direction="W" name="Costa Rica" /> <neighbor direction="E" name="Colombia" /> </country> </data>
导入xml模块并获取根节点
import xml.etree.ElementTree as ET #导入模块名称较长时可以取别名 tree = ET.parse("xml_lesson") #获取根节点 root = tree.getroot() #获取根节点标签 print(root.tag)
遍历整个文档
for child in root: print(child.tag, child.attrib) #获取子节点标签、属性 for i in child: print(i.tag, i.attrb, i.text) #获取子节点的子节点的标签、属性和值
只遍历year节点
for node in root.iter('year'): print(node.tag, node.text)
修改year节点
for node in root.iter('year'): new_year = int(node.text) + 1 #将year节点的值转换为int,再加1 node.text = str(new_year) #将上述计算得到新的值转换为字符串重新赋给year节点的值 node.set("updated", "yes") #给year节点增加属性update,属性值为yes tree.write("xml_test") #将上述修改和增加写入文档,此处可写入一个新的文档,也可写入原文档
删除指定节点
for country in root.findall('country'): #查找root下的所有country节点 rank = int(country.find('rank').text) #查找country节点下的rank节点,并获取rank节点的值 if rank > 50: root.remove(country) #如果节点的值大于50,则删除整个country节点 tree.write('output.xml') #将上述操作写入文档
通过python语句生成xml文档
import xml.etree.ElementTree as ET new_xml = ET.Element("namelist") #生成名为new_xml的文档,根节点标签为namelist name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"}) #生成new_xml的子节点,子节点标签为name,属性为enrolled,属性值为yes age = ET.SubElement(name, "age", attrib={"checked": "no"}) #生成name的子节点,标签为age,属性为checked,属性值为no sex = ET.SubElement(name, "sex") #生成name的子节点,标签为sex sex.text = '33' #set标签的值为‘33’ 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) # 打印生成的格式
通过上述命令生成的new_xml文件的内容如下
<namelist> <name enrolled='yes'> <age checked='no'> <sex>33</sex> </name> <name enrolled='no'> <age>19</age> </name> </namelist>