collections模块

在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

  • namedtuple:生成可以使用名字来访问元素内容的tuple
  • deque:双端队列,可以快速的从另外一侧追加和推出对象
  • Counter:计数器,主要用来计数
  • OrderedDict:有序字典
  • defaultdict:带有默认值的字典

namedtuple

我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:

p = (1, 2)

但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的。

这时,namedtuple就派上了用场:

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
p = Point(1, 2)
print(p.x) #
print(p.y) #

类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:

#namedtuple('名称', [属性list]):
Circle = namedtuple('Circle', ['x', 'y', 'r'])

queue:队列

#put()放值、get()取值
import queue
q = queue.Queue()
q.put([1,2,3])
q.put(5)
q.put(6)
print(q.get()) #[1, 2, 3]
print(q.get()) #
print(q.get()) #

deque

使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。

deque是为了高效实现插入和删除操作的双向列表,适合用于队列和堆栈:

  • 队列 :先进先出
  • 堆栈 :先进后出
from collections import deque

dq = deque([1, 3])
dq.append("a") # [1, 3, "a"] 从后面放数据
dq.appendleft("b") # ["b", 1, 3, "a"] 从前面放数据
dq.insert(2, 2) # ["b", 1, 2, 3,"a"] 在第二个位置插入2 print(dq) # deque(['b', 1, 2, 3, 'a']) print(dq.pop()) # a 从后面取数据
print(dq.popleft()) # b 从前面取数据
print(dq) # deque([1, 2, 3])

OrderedDict

使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序;如果要保持Key的顺序,可以用 OrderedDict。

from collections import OrderedDict

# dict的Key是无序的
dic = dict([("a", 1), ("b", 2), ("c", 3)])
print(dic) # 可能是 {'a': 1, 'c': 3, 'b': 2} # OrderedDict的Key是有序的
o_dic = OrderedDict([("a", 1), ("b", 2), ("c", 3)])
print(o_dic) # OrderedDict([('a', 1), ('b', 2), ('c', 3)])

注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:

from collections import OrderedDict

o_dic = OrderedDict()
o_dic["a"] = 1
o_dic["b"] = 2
o_dic["c"] = 3
print(o_dic.keys()) # 按照插入的Key的顺序返回
# odict_keys(['a', 'b', 'c'])

defaultdict

有如下值集合 [11, 22, 33, 44, 55, 66, 77, 88, 99],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。

from collections import defaultdict

l = [11, 22, 33, 44, 55, 66, 77, 88, 99]
dic = defaultdict(list) for item in l:
if item > 66:
dic["k1"].append(item)
else:
dic["k2"].append(item)
print(dic)
#defaultdict(<class "list">, {"k2": [11, 22, 33, 44, 55, 66], "k1": [77, 88, 99]})

Counter

Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。

from collections import Counter

c = Counter('abcdeabcdabcaba')
print(c) # Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})

random模块

import random

# 随机小数
print(random.random()) # 大于0小于1的小数
print(random.uniform(6, 8)) # 大于6小于8的小数 # 随机整数
print(random.randint(1, 5)) # 大于等于1小于等于5的整数
print(random.randrange(1, 10, 2)) # 大于等于1且小于10之间的奇数,2为步长 # 随机选择一个返回
print(random.choice([1, "a", [2, 3]])) # 1或者"a"或者[2, 3] # 随机选择多个返回,返回的个数为函数的第二个参数
print(random.sample([1, "a", [2, 3]], 2)) # 列表元素任意2个组合 # 打乱列表顺序
item = [1, 3, 5, 7, 9]
random.shuffle(item) # 打乱顺序
print(item)
import random

def random_verify_code():
code = ""
for i in range(5):
num = random.randint(0, 9)
upper_alpha = chr(random.randint(65, 90))
lower_alpha = chr(random.randint(97, 122))
item = random.choice([num, upper_alpha, lower_alpha])
code = "".join([code, str(item)])
return code print(random_verify_code())

随机验证码

hashlib模块

Python的hashlib模块提供了常见的摘要算法;如MD5,SHA1等...

以常见的摘要算法MD5为例,计算出一个字符串的MD5值:

import hashlib

md5 = hashlib.md5()
md5.update(b"how to use md5 in python hashlib?")
print(md5.hexdigest())

如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:

import hashlib

md5 = hashlib.md5()
md5.update(b"how to use md5 in ")
md5.update(b"python hashlib?")
print(md5.hexdigest())

由于常用口令的 md5 值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的 md5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:

import hashlib

md5 = hashlib.md5(bytes("salt", encoding="utf-8"))  # "salt"可替换成任意字符串
md5.update(b"how to use md5 in python hashlib?")
print(md5.hexdigest())

经过加盐处理的MD5口令,只要Salt不被黑客知道,即使用户输入简单口令,也很难通过MD5反推明文口令。

但是如果有两个用户都使用了相同的简单口令比如123456,在数据库中,将存储两条相同的MD5值,这说明这两个用户的口令是一样的。有没有办法让使用相同口令的用户存储不同的MD5呢?

如果假定用户名唯一,就可以通过把用户名作为Salt的一部分来计算MD5,从而实现相同口令的用户也存储不同的MD5。

摘要算法在很多地方都有广泛的应用。要注意摘要算法不属于加解密算法,不能用于加密(因为无法通过摘要反推明文),只能用于防篡改,但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口令。

import hashlib

username = input("username:")
password = input("password:")
md5 = hashlib.md5(bytes(username, encoding="utf-8"))
md5.update(bytes(password, encoding="utf-8"))
md5_password = md5.hexdigest()
if username == "pd" and md5_password == "bf55109f7e511ebf6d8f1f43a5a96539":
print("登录成功")

configparser模块

该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值)。

创建文件

来看一个好多软件的常见文档格式如下:

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes [bitbucket.org]
User = hg [topsecret.server.com]
Port = 50022
ForwardX11 = no

如果想用python生成一个这样的文档怎么做呢?

import configparser
config = configparser.ConfigParser() config['DEFAULT'] = {'ServerAliveInterval': '',
'Compression': 'yes',
'CompressionLevel': '',
'ForwardX11': 'yes'}
config['bitbucket.org'] = {'User': 'hg'}
config['topsecret.server.com'] = {'Host Port': '', 'ForwardX11': 'no'} with open('example.ini', 'w') as configfile:
config.write(configfile)

增删改操作

import configparser
config = configparser.ConfigParser() #查找文件内容,基于字典的形式 print(config.sections()) # [] 没读文件,得到的是空 config.read('example.ini', encoding='utf-8') #读文件 print(config.sections()) # 获取所有节点 ['bitbucket.org', 'topsecret.server.com'] print(config.items("bitbucket.org")) # 获取指定节点下所有的键值对(如果有DEFAULT节点,默认也获取) print(config.get('bitbucket.org','compression')) # 获取指定节点下指定key的值
print(config['bitbucket.org']["user"]) # 获取指定节点下指定key的值 print('bytebong.com' in config) # False
print('bitbucket.org' in config) # True for key in config['bitbucket.org']: # 如果有DEFAULT节点的话,默认也同时获取key
print(key) print(config.options('bitbucket.org')) # 返回的是由key组成的列表

检查、添加、修改、删除

import configparser
config = configparser.ConfigParser()
config.read("example.ini", encoding="utf-8") # 检查节点
has_sec = config.has_section("bitbucket.org")
print(has_sec) # True # 添加新节点
config.add_section("xxx")
config.write(open("example.ini", "w")) # 修原有改节点键值对
config.set('section', 'key', 'value')
config.write(open('filename', 'w')) # 添加新节点,同时定义一对键值对
config.add_section('new_section')
config.set('new_section', 'new_key', "new_value")
config.write(open('filename', 'w')) # 删除节点
config.remove_section('bitbucket.org')
config.write(open("example.ini", "w"))

logging模块

用于便捷记录日志且线性安全的模块

1、单文件日志(不推荐)

import logging
logging.basicConfig(filename="log.log",
level=logging.DEBUG,
format="%(asctime)s - %(module)s/%(filename)s[line:%(lineno)d] - %(levelname)s:%(message)s",
datefmt="%d-%b-%Y %H:%M:%S",
filemode="w") logging.debug("debug message") #排错信息
logging.info("info message") #正常信息
logging.warning("warning message") #警告信息
logging.error("error message") #错误信息
logging.critical("critical message") #严重错误信息

2、多文件日志(推荐)

对于上述记录日志的功能,只能将日志记录在单文件中,如果想要设置多个日志文件,logging.basicConfig将无法完成,需要自定义文件和日志操作对象。

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 -----用户输出的消息

 logger对象配置流程

import logging
logger = logging.getLogger() # 设置日志级别
logger.setLevel(logging.DEBUG) # 创建一个handler(或者多个),用于写入日志文件
fh = logging.FileHandler('log', encoding='utf-8')
# 创建一个handler,用于输出到控制台
sh = logging.StreamHandler() # 输出格式,可定义多个
formatter = logging.Formatter('%(asctime)s - %(module)s/%(filename)s[line:%(lineno)d] - %(levelname)s:%(message)s') # handler 关联 输出格式
fh.setFormatter(formatter)
sh.setFormatter(formatter) # logger对象可以添加多个fh和sh对象
logger.addHandler(fh)
logger.addHandler(sh) # 写日志,括号内可写任意内容
logger.debug('排错信息')
logger.info('正常信息')
logger.warning('警告信息')
logger.error('错误信息')
logger.critical('严重错误信息')

logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口;Handler发送日志到适当的目的地;Filter提供了过滤日志信息的方法;Formatter指定日志显示格式;另外,可以通过logger.setLevel(logging.Debug)设置级别。

collections、random、hashlib、configparser、logging模块的更多相关文章

  1. 内置函数 hashlib configparser logging 模块 C/S B/S架构

    1.内置函数 # 内置的方法有很多 # 不一定全都在object中 # class Classes: # def __init__(self,name): # self.name = name # s ...

  2. hashlib,configparser,logging模块

    一.常用模块二 hashlib模块 hashlib提供了常见的摘要算法,如md5和sha1等等. 那么什么是摘要算法呢?摘要算法又称为哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度 ...

  3. hashlib,configparser,logging,模块

    一,hashlib模块 算法介绍 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一 ...

  4. 常用模块之hashlib,configparser,logging模块

    常用模块二 hashlib模块 hashlib提供了常见的摘要算法,如md5和sha1等等. 那么什么是摘要算法呢?摘要算法又称为哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定 ...

  5. 常用模块(hashlib,configparser,logging)

    常用模块(hashlib,configparser,logging) hashlib hashlib 摘要算法的模块md5 sha1 sha256 sha512摘要的过程 不可逆能做的事:文件的一致性 ...

  6. 序列化 ,hashlib ,configparser ,logging ,collections模块

    # 实例化 归一化 初始化 序列化 # 列表 元组 字符串# 字符串# .......得到一个字符串的结果 过程就叫序列化# 字典 / 列表 / 数字 /对象 -序列化->字符串# 为什么要序列 ...

  7. python3之xml&ConfigParser&hashlib&Subprocess&logging模块

    1.xml模块 XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言. XML 被设计用来传输和存储 ...

  8. 常用模块(subprocess/hashlib/configparser/logging/re)

    一.subprocess(用来执行系统命令) import os cmd = r'dir D:xxx | findstr "py"' # res = subprocess.Pope ...

  9. python常用模块补充hashlib configparser logging,subprocess模块

    一.hashlib模板 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度固定 ...

  10. python_模块 hashlib ,configparser, logging

    hashlib模块 算法介绍 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长 ...

随机推荐

  1. BeautifulSoup中各种html解析器的比較及使用

    Beautiful Soup解析器比較 ·Beautiful Soup支持各种html解析器.包含python自带的标准库.还有其它的很多第三方库模块. 当中一个就是lxml parser,至于lxm ...

  2. cojs 1175. [顾研NOIP] 旅游电车

    1175. [顾研NOIP] 旅游电车 ★★☆   输入文件:buss.in   输出文件:buss.out   简单对比时间限制:1 s   内存限制:256 MB [问题描述] Henryy国正致 ...

  3. vim g 和 % 区别

    vim中的g(global)和%的区别: g:全局的 s/pattern/replacement/  : 替换行中出现的每一个pattern g/pattern/s/pattern/replaceme ...

  4. android电池管理系统

    原文:http://www.2cto.com/kf/201408/326462.html 1.概述 随着移动智能设备的快速发屏,电池的续航能力在很大情况下诱导了大众消费者的购买选择,android系统 ...

  5. tab不显示为空格

  6. 【Codeforces】Round #375 (Div. 2)

    Position:http://codeforces.com/contest/723 我的情况 啊哈哈,这次raiting肯定要涨,接受过上次的教训,先用小号送肉,大号都是一发切,重回蓝咯 结果... ...

  7. 【Angular】过滤器

    AngularJS学习笔记 {{ name | uppercase}} {{ 123.456789 | number:2 }} app.controller('DemoController', ['$ ...

  8. MSP430:PWM产生

    #define     PWM                      BIT6 //  Description: This program generates one PWM output on ...

  9. IE下元素设置百分比的问题

    场景:近两天在做一个控件,该控件是一个tab型的,并且该tab有可能是两个tab标签,也有可能是多个tab标签,为了能够适应这种动态需求, 在设置标签宽度的时候,直接用的最外层容器除以tab的个数,然 ...

  10. selenium3 + python - action_chains源码分析

    ActionChains简介 actionchains是selenium里面专门处理鼠标相关的操作如:鼠标移动,鼠标按钮操作,按键和上下文菜单(鼠标右键)交互.这对于做更复杂的动作非常有用,比如悬停和 ...