configparser模块
该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值)
创建文件
import configparser
config = configparser.ConfigParser()
config["DEFAULT"] = {'a': '45',
'Compression': 'yes',
'CompressionLevel': '9',
'ForwardX11': 'yes'
}
config['bitbucket.org'] = {'User': 'hg'}
config['topsecret.server.com'] = {'Host Port': '50022','ForwardX11': 'no'}
with open('example.ini', 'w') as f:
config.write(f)
执行结果
生成一个example.ini文件,内容如下
[DEFAULT]
forwardx11 = yes
compression = yes
compressionlevel = 9
a = 45
[bitbucket.org]
user = hg
[topsecret.server.com]
host port = 50022
forwardx11 = no
查看所有sections
import configparser
config = configparser.ConfigParser()
# 查找文件内容,基于字典的形式
print(config.sections()) # [] 没有读取文件,所以打印一个空列表
config.read('example.ini') # 读取example.ini文件
print(config.sections()) # 打印‘节’, DEFAULT有特殊意义:相当于全局变量一样的意思
# 结果['bitbucket.org', 'topsecret.server.com']
print('bytebong.com' in config) # 判断节bytebong是否在config里面 返回 True or False
print('bitbucket.org' in config) # 判断节bitbucket.org是否在config里面 返回 True or False
print(config['bitbucket.org']["user"]) # 打印节'bitbucket.org'的"user"对应的值 # hg
print(config['DEFAULT']['Compression']) # 打印节'DEFAULT'的'Compression'对应的值 # yes
print(config['topsecret.server.com']['ForwardX11']) # 打印节'topsecret.server.com'的'ForwardX11'对应的值 # no
print(config['bitbucket.org']) #
增删改操作
import configparser
config = configparser.ConfigParser() # 实例化一个对象config
config.read('example.ini') # 读取example.ini文件
config.add_section('yuan') # 添加一个'yuan'节
config.remove_section('bitbucket.org') # 删除一个'bitbucket.org'节
config.remove_option('topsecret.server.com',"forwardx11") # 删除'topsecret.server.com'节里面的"forwardx11"
config.set('topsecret.server.com','k1','11111') # 添加'topsecret.server.com'节里面的'k1'对应'11111'
config.set('yuan','k2','22222') # 添加'yuan'节里面的'k2'对应'22222'
config.write(open('new2.ini', "w")) # 打开一个新的文件new2.ini,并写入文件
执行结果生成一个new2.ini文件,内容如下
[DEFAULT]
forwardx11 = yes
compression = yes
compressionlevel = 9
a = 45
[topsecret.server.com]
host port = 50022
k1 = 11111
[yuan]
k2 = 22222
logging模块
所有的增删改都要记录日志,为了保护数据安全,错误排除等等......
在内部操作的时候提供很多便利
给用户提供更多的信息
在程序使用的过程中自己调试需要看你的信息
帮助程序员排查问题
logging模块 不会自动帮你添加日志的内容,需要人为设定
logging简单配置
默认情况下python的logging模块将日志打印到了标准输出中,且只显示了大于等于warning级别的日志,这说明默认的日志级别设置为warning(日志级别等级critical>error>warning>info>debug),默认的日志格式为日志级别:Logger名称:用户输入消息
示例:
import logging
logging.debug('I am debug')
logging.info('I am info')
logging.warning('I am warning')
logging.error('I am error')
logging.critical('I am critical')
执行结果
WARNING:root:I am warning
ERROR:root:I am error
CRITICAL:root:I am critical
能不能输出所有的日志,改成如下
能不能只显示某一个级别的信息呢?不行,只能打印某个级别以上的日志信息
import logging
logging.basicConfig(level=logging.DEBUG) # 或者改成 logging.basicConfig(level=10)
logging.debug('I am debug')
print('logging.DEBUG = {}'.format(logging.DEBUG))
logging.info('I am info')
print('logging.INFO = {}'.format(logging.INFO))
logging.warning('I am warning')
print('logging.WARNING = {}'.format(logging.WARNING))
logging.error('I am error')
print('logging.ERROR = {}'.format(logging.ERROR))
logging.critical('I am critical')
print('logging.CRITICAL = {}'.format(logging.CRITICAL))
执行结果,所有的都显示出来了
DEBUG:root:I am debug
INFO:root:I am info
logging.DEBUG = 10
WARNING:root:I am warning
logging.INFO = 20
ERROR:root:I am error
logging.WARNING = 30
CRITICAL:root:I am critical
logging.ERROR = 40
logging.CRITICAL = 50
更改日志格式
import logging
# 默认情况下 只显示 警告 及警告级别以上信息
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %y %H:%M:%S', # 日志格式
filename='userinfo.log' # 写入文件 userinfo.log
)
logging.debug('debug message') # debug 调试模式 级别最低
logging.info('info message') # info 显示正常信息
logging.warning('warning message') # warning 显示警告信息
logging.error('error message') # error 显示错误信息
logging.critical('critical message') # critical 显示严重错误信息
文件内容如下
Mon, 23 Apr 18 20:31:24 lianxi.py[line:155] DEBUG debug message
Mon, 23 Apr 18 20:31:24 lianxi.py[line:156] INFO info message
Mon, 23 Apr 18 20:31:24 lianxi.py[line:157] WARNING warning message
Mon, 23 Apr 18 20:31:24 lianxi.py[line:158] ERROR error message
Mon, 23 Apr 18 20:31:24 lianxi.py[line:159] CRITICAL critical message
配置参数说明:
logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:
filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
format参数中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息
logging简单配置编码格式不能设置,不能同时输出到文件和屏幕
logger对象配置
高可定制化
首先创造logger对象
创造文件句柄,屏幕句柄
创造格式
使用文件句柄和屏幕句柄 绑定格式
logger对象和句柄关联
屏幕句柄.setLevel(logging.WARNING) 设置屏幕输出日志级别
logger.setLevel(logging.DEBUG) 设置文件记录级别
示例
import logging
logger = logging.getLogger() # 实例化了一个logger对象
fh = logging.FileHandler('test.log', encoding='utf-8') # 实例化了一个文件句柄fh
sh = logging.StreamHandler() # 输出到屏幕
fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 定制日志输出格式
fh.setFormatter(fmt) # 格式和文件句柄或者屏幕句柄关联
sh.setFormatter(fmt)
sh.setLevel(logging.WARNING) # 屏幕输出warning以上级别信息
logger.addHandler(fh) # 和logger关联的只有句柄
logger.addHandler(sh)
logger.setLevel(logging.DEBUG) # 文件记录debug以上所有信息
logger.debug('debug message') # debug 调试模式 级别最低
logger.info('info message') # info 显示正常信息
logger.warning('warning message') # warning 显示警告信息
logger.error('error message') # error 显示错误信息
logger.critical('critical message') # critical 显示严重错误信息
屏幕输出信息
2018-04-23 20:46:11,820 - root - WARNING - warning message
2018-04-23 20:46:11,820 - root - ERROR - error message
2018-04-23 20:46:11,820 - root - CRITICAL - critical message
文件记录信息
2018-04-23 20:46:11,820 - root - DEBUG - debug message
2018-04-23 20:46:11,820 - root - INFO - info message
2018-04-23 20:46:11,820 - root - WARNING - warning message
2018-04-23 20:46:11,820 - root - ERROR - error message
2018-04-23 20:46:11,820 - root - CRITICAL - critical message
collections模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等
1.namedtuple: 生成可以使用名字来访问元素内容的tuple
2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
3.Counter: 计数器,主要用来计数
4.OrderedDict: 有序字典
5.defaultdict: 带有默认值的字典
namedtuple
tuple元组,表示不变集合,例如,一个点的二维坐标就可以表示成:
from collections import namedtuple
test = namedtuple('hello', ['x', 'y'])
p = test(1, 2)
print(p.x)
print(p.y)
执行结果
1
2
类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义,里面的值不可修改(元组不可变),修改会报错
from collections import namedtuple
Circle = namedtuple('Circle', ['x', 'y', 'z'])
p = Circle(3, 4, 5)
print(p.x)
print(p.y)
print(p.z)
执行结果
3
4
5
deque 双端队列
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈
计算机数据结构模型
先进先出:
队列,内部维护了严格的顺序,不能跳着取,必须一个个取
双端队列 两边(前,后)同时取,写 from collections import deque
队列 单向 import queue
先进后出:栈 单向
双端队列示例
from collections import deque
# 双端队列
dq = deque() # 创建双端队列
dq.append(1) # 插入数据,追加到最后
dq.append(2) # 插入数据,追加到最后
dq.append(3) # 插入数据,追加到最后
print(dq)
print(dq.pop()) # 取一个值(取走,队列中就没有了)
print(dq.popleft()) # 从左边取值
dq.appendleft(4) # 从左边插入数据
dq.appendleft(5) # 从左边插入数据
print(dq)
执行结果
deque([1, 2, 3])
3
1
deque([5, 4, 2])
队列是为了维护秩序的(例如:抢票,请求之类的),如果需要用到增删改查,不适合用队列
双端队列:deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素
OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict
from collections import OrderedDict
# 有序字典,谁先写在前面,就排在前面
dic = OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
dic1 = OrderedDict([('k3', 'v3'), ('k2', 'v2'), ('k1', 'v1')])
dic2 = OrderedDict([('k2', 'v2'), ('k3', 'v3'), ('k1', 'v1')])
print(dic)
print(dic1)
print(dic2)
执行结果
OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
OrderedDict([('k3', 'v3'), ('k2', 'v2'), ('k1', 'v1')])
OrderedDict([('k2', 'v2'), ('k3', 'v3'), ('k1', 'v1')])
注意,OrderedDict
的Key会按照插入的顺序排列,不是Key本身排序
from collections import OrderedDict
od = OrderedDict()
od['z'] = 1 # 按照插入的key的顺序返回
od['y'] = 3
od['x'] = 2
print(od)
执行结果
OrderedDict([('z', 1), ('y', 3), ('x', 2)])