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