python3--模块configparser,logging,collections

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)])

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Hongten

JSP 三讲

4401
来自专栏编程坑太多

springboot(18)common-boot

1544
来自专栏养码场

Java后端开发面大集锦1.0,汇集了各大公司的面试点!你都能答上来吗?

各位在面试时,必然会遇到各位的技术问题。这次针对Java后端开发,以下这篇文章罗列了各大公司技术面试官可能会提及的问题,并做出了解答。若觉得不错,希望分享给更多...

643
来自专栏Golang语言社区

Golang Template 简明笔记

作者:人世间 链接:https://www.jianshu.com/p/05671bab2357 來源:简书 前后端分离的Restful架构大行其道,传统的模板...

9186
来自专栏PHP在线

YII运行原理

应用执行流程: 浏览器向服务器发送 Http Request | 控制器(protected/controllers) | |—> Action | 创建模型 ...

3356
来自专栏coder修行路

Beego 框架学习(一)

 Beego官网本身已经整理的非常详细了,但是作为一个学习者,我还是决定自己好好整理一下,这样在后面使用的时候自己对每部分才能非常熟悉,即使忘记了,也可以迅速定...

5608
来自专栏屈定‘s Blog

Java--死锁以及死锁的排查

清单一代码有点长,但是逻辑很简单,有两个临界区变量lockA,lockB,线程A先获取到lockA在获取lockB,线程B则与之相反顺序获取锁,那么就可能会有以...

5923
来自专栏有趣的django

Flask快速入门 flask快速入门

2180
来自专栏程序员宝库

用Python处理ZIP压缩包

标准库模块zipfile可以用来处理zip压缩包。 测试zip文件 is_zipfile()方法返回一个布尔值,说明参数传入的路径所代表的文件是不是一个zip压...

48912
来自专栏蓝天

C/C++常见gcc编译链接错误解决方法

用“-Wl,-Bstatic”指定链接静态库,使用“-Wl,-Bdynamic”指定链接共享库,使用示例: -Wl,-Bstatic -lmysq...

3353

扫码关注云+社区

领取腾讯云代金券