xml处理模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
import xml.etree.ElementTree as ET tree = ET.parse("country.xml") root = tree.getroot() # 获得根节点 print(root.tag) # 遍历xml文档 for child in root: print(child.tag,child.attrib) for i in child: print("-->",i.tag,i.text)
import xml.etree.ElementTree as ET tree = ET.parse("country.xml") root = tree.getroot() # get the root node #只获得year节点 for node in root.iter('year'): print(node.tag,node.text)
#修改 for node in root.iter('year'): new_year = int(node.text)+1 node.text = str(new_year) node.set("updated","yes") tree.write("xml_test2.xml")
#删除 for country in root.findall("country"): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write("xml_test2.xml")
#create new_xml = ET.Element("namelist")#root name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"}) age = ET.SubElement(name,"age",attrib={"checked":"no"}) sex = ET.SubElement(name,"sex") sex.text = '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("new_test.xml", encoding="utf-8",xml_declaration=True) ET.dump(new_xml) #打印生成的格式
ConfigParser模块
用于生成和修改常见配置文档
[DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel = 9 ForwardX11 = yes [bitbucket.org] User = hg [topsecret.server.com] Port = 50022 ForwardX11 = no
对配置文件操作
#生成配置文件 import configparser config = configparser.ConfigParser() config.read('example6.ini') config["DEFAULT"] = {'ServerAliveInterval': '45', 'Compression': 'yes', 'CompressionLevel': '9'} 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 config['DEFAULT']['ForwardX11'] = 'yes' with open('example.ini', 'w') as configfile: config.write(configfile) # 删除指定模块 sec = config.remove_section('bitbucket.org') config.write(open('example4.ini','w')) #删除模块下的指定项目 config.remove_option('alan','age') config.write(open('example6.ini','w')) #判断模块名是否存在不存在就创建 sec = config.has_section('alan') config.add_section('alan') config['alan']['age']="21" config.write(open('example6.ini','w')) #改写模块下的指定项目 config.set('alan','age','22') config.write(open('example6.ini','w'))
hashlib模块
用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512
>>> import hashlib >>> a =hashlib.md5() >>> a.update(b"Hello") >>> a.update(b"it's me") >>> a.digest() #二进制 b'\xc3\xb8Fk,fV\x9c\xd3\x01\x15\xdf\xd3\x9bd\xb8' >>> a.hexdigest() #16进制 'c3b8466b2c66569cd30115dfd39b64b8' >>> b = hashlib.sha512() >>> b.update(b'Hello') >>> b.digest() b'6\x15\xf8\x0c\x9d)>\xd7@&\x87\xf9K"\xd5\x8eR\x9b\x8c\xc7\x91o\x8f\xac\x7f\xdd\xf7\xfb\xd5\xafL\xf7w\xd3\xd7\x95\xa7\xa0\n\x16\xbf~\x7f?\xb9V\x1e\xe9\xba\xaeH\r\xa9\xfez\x18v\x9eq\x88k\x03\xf3\x15' >>> b.hexdigest() '3615f80c9d293ed7402687f94b22d58e529b8cc7916f8fac7fddf7fbd5af4cf777d3d795a7a00a16bf7e7f3fb9561ee9baae480da9fe7a18769e71886b03f315'
hmac模块
python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
>>> import hmac >>> a=hmac.new(b"secret_key") >>> a.update(b"Hello") >>> a.digest() b'RF\r"\xec~@-\xc8\xc6*\xed\xa5\x1e\xc9 ' >>> a.hexdigest() '52460d22ec7e402dc8c62aeda51ec920'
Subprocess模块
运行python的时候,我们都是在创建并运行一个进程。像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序。
subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。
>>> subprocess.run(["ls", "-l"]) # doesn't capture output CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE) CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')
调用subprocess.run(...)是推荐的常用方法,在大多数情况下能满足需求,但如果你可能需要进行一些复杂的与系统的交互的话,你还可以用subprocess.Popen(),语法如下:
p = subprocess.Popen("find / -size +1000000 -exec ls -shl {} \;",shell=True,stdout=subprocess.PIPE) print(p.stdout.read())#显示执行结果
可用参数:
- args:shell命令,可以是字符串或者序列类型(如:list,元组)
- bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
- stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
- preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
- close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。 - shell:同上
- cwd:用于设置子进程的当前目录
- env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
- universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
- startupinfo与createionflags只在windows下有效
将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
终端输入的命令分为两种:
- 输入即可得到输出,如:ifconfig
- 输入进行某环境,依赖再输入,如:python
交互实例
import subprocess obj = subprocess.Popen(["python"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) obj.stdin.write("print('hello')\n") obj.stdin.write("print('hello1')\n") obj.stdin.write("print('hello2')\n") obj.stdin.write("print('hello3')\n") out_error_list = obj.communicate() print(out_error_list)
logging模块
很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug()
, info()
, warning()
, error()
and critical() 5个级别
Level | When it’s used |
---|---|
DEBUG |
Detailed information, typically of interest only when diagnosing problems. |
INFO |
Confirmation that things are working as expected. |
WARNING |
An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
ERROR |
Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL |
A serious error, indicating that the program itself may be unable to continue running. |
实例
import logging logging.basicConfig(filename='example2.log',level=logging.ERROR)#创建日志文件并设定级别 logging.debug('This message should go to the log file') #当级别为debug时打印的信息 logging.info('So should this') logging.warning('And this, too')#除了level设置为error意外的任何一个级别都会打印
格式化输出
import logging logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S ') logging.warning('is when this event was logged.')
输出文件并输出到屏幕
#create logger logger = logging.getLogger('TEST-LOG') logger.setLevel(logging.DEBUG) # create console handler and set level to debug ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # create file handler and set level to warning fh = logging.FileHandler("access.log") fh.setLevel(logging.WARNING) # create formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # add formatter to ch and fh ch.setFormatter(formatter) fh.setFormatter(formatter) # add ch and fh to logger logger.addHandler(ch) logger.addHandler(fh) # 'application' code logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message')
对于格式,有如下属性可是配置:
用于便捷记录日志且线程安全的模块
mport logging logging.basicConfig(filename='log.log', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', level=10) logging.debug('debug') logging.info('info') logging.warning('warning') logging.error('error') logging.critical('critical') logging.log(10,'log')
等级:
只有大于当前日志等级的操作才会被记录。
CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0