提供一些随机数获取的相关方法
1.random():获取[0.0,1.0)范围内的浮点数
2.randint(a,b):获取[a,b]范围内的整数
3.uniform(a,b): 获取[a,b]范围内的浮点数
4.shuffle(a):将序列的所有元素随机排序
5.sample(a,b):从a中随机抽取b个元素,可用于变向打乱元组(从a中抽取全部元素)
提供一些日期、时间获取和操作的方法
1.time():获取时间戳(1970-1-1 00:00:00到目前)
2.gmtime():获取格林威治时间(格式化)
3.localtime():获取标准时间(格式化)
4.strftime(‘字符串’):格式化时间对象转时间字符串
5.strptime(a,b):时间字符串转换时间对象
6.mktime(a):结构化时间转换时间戳
7.sleep(a):休眠当前程序a秒
1.时间戳:时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量,是计算机能够识别的时间
2.元组(struct_time):struct_time元组共有9个元素共九个元素(年,月,日,时,分,秒,一年中第几周,一年中第几天等),用来操作时间的
索引(Index) | 属性(Attribute) | 值(Values) |
---|---|---|
0 | tm_year(年) | 比如2020 |
1 | tm_mon(月) | 1 - 12 |
2 | tm_mday(日) | 1 - 31 |
3 | tm_hour(时) | 0 - 23 |
4 | tm_min(分) | 0 - 59 |
5 | tm_sec(秒) | 0 - 60 |
6 | tm_wday(weekday) | 0 - 6(0表示周一) |
7 | tm_yday(一年中的第几天) | 1 - 366 |
8 | tm_isdst(是否是夏令时) | 默认为0 |
3.格式化的时间字符串:例如‘2020-8-28’,人能够看懂的时间
格式化符号 | 对应关系 |
---|---|
%y | 两位数的年份表示(00-99) |
%Y | 四位数的年份表示(000-9999) |
%m | 月份(01-12) |
%d | 月内中的一天(0-31) |
%H | 24小时制小时数(0-23) |
%I | 12小时制小时数(01-12) |
%M | 分钟数(00=59) |
%S | 秒(00-59) |
%a | 本地简化星期名称 |
%A | 本地完整星期名称 |
%b | 本地简化的月份名称 |
%B | 本地完整的月份名称 |
%c | 本地相应的日期表示和时间表示 |
%j | 年内的一天(001-366) |
%p | 本地A.M.或P.M.的等价符 |
%U | 一年中的星期数(00-53)星期天为星期的开始 |
%w | 星期(0-6),星期天为星期的开始 |
%W | 一年中的星期数(00-53)星期一为星期的开始 |
%x | 本地相应的日期表示 |
%X | 本地相应的时间表示 |
%Z | 当前时区的名称 |
%% | %号本身 |
```python
#导入时间模块
import time
#格式化时间 ----> 结构化时间
ft = time.strftime('%Y/%m/%d %H:%M:%S')
st = time.strptime(ft, '%Y/%m/%d %H:%M:%S')
print(st)
#结构化时间 ---> 时间戳
t = time.mktime(st)
print(t)
#时间戳 ----> 结构化时间
t = time.time()
st = time.localtime(t)
print(st)
#结构化时间 ---> 格式化时间
ft = time.strftime('%Y/%m/%d %H:%M:%S', st)
print(ft)
import time
#结构化时间 --> %a %b %d %H:%M:%S %Y串
st = time.localtime(2500000000)
res1 = time.asctime(st)
print(res1)
#时间戳 --> %a %d %d %H:%M:%S %Y串
c1 = time.ctime()
print(c1)
t = time.time()
ft = time.ctime(2500000000)
print(ft)
1.date(a):生成日期对象(子属性:year、month、day)
2.time(a):生成时间对象(子属性:hour、minute、secound)
3.datetime(a):生成日期时间对象(子属性:6个)
4.timedelta(days=2):创建一个日期时间段,多用于时间计算
#导入日期模块
import datetime
now_time = datetime.datetime.now() # 现在的时间
#只能调整的字段:weeks days hours minutes seconds
print(datetime.datetime.now() + datetime.timedelta(weeks=3)) # 三周后
print(datetime.datetime.now() + datetime.timedelta(weeks=-3)) # 三周前
print(datetime.datetime.now() + datetime.timedelta(days=-3)) # 三天前
print(datetime.datetime.now() + datetime.timedelta(days=3)) # 三天后
print(datetime.datetime.now() + datetime.timedelta(hours=5)) # 5小时后
print(datetime.datetime.now() + datetime.timedelta(hours=-5)) # 5小时前
print(datetime.datetime.now() + datetime.timedelta(minutes=-15)) # 15分钟前
print(datetime.datetime.now() + datetime.timedelta(minutes=15)) # 15分钟后
print(datetime.datetime.now() + datetime.timedelta(seconds=-70)) # 70秒前
print(datetime.datetime.now() + datetime.timedelta(seconds=70)) # 70秒后
current_time = datetime.datetime.now()
#可直接调整到指定的 年 月 日 时 分 秒 等
print(current_time.replace(year=1977)) # 直接调整到1977年
print(current_time.replace(month=1)) # 直接调整到1月份
print(current_time.replace(year=1989,month=4,day=25)) # 1989-04-25 18:49:05.898601
#将时间戳转化成时间
print(datetime.date.fromtimestamp(1232132131)) # 2009-01-17
os模块是与操作系统交互的一个接口
1.getcwd() :获取当前工作目录,即当前python脚本工作的目录路径
2.chdir(“dirname”): 改变当前脚本工作目录;相当于shell下cd
3.curdir: 返回当前目录: (’.’)
4.pardir: 获取当前目录的父目录字符串名:(’…’)
1.makedirs(‘dirname1/dirname2’) 可生成多层递归目录
2.removedirs(‘dirname1’) 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
3.mkdir(‘dirname’) 生成单级目录;相当于shell中mkdir dirname
4.rmdir(‘dirname’) 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
5.listdir(‘dirname’) 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
1.remove() 删除一个文件
2.rename(“oldname”,“newname”) 重命名文件/目录
3.stat(‘path/filename’) 获取文件/目录信息
1.sep 输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"
2.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
3.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:
4.name 输出字符串指示当前使用平台。win->‘nt’; Linux->‘posix’
1.system(“bash command”) 运行shell命令,直接显示
2.popen("bash command).read() 运行shell命令,获取执行结果
3.environ 获取系统环境变量
1.path.abspath(path) 返回path规范化的绝对路径
2.path.split(path) 将path分割成目录和文件名二元组返回
3.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
4.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值,即os.path.split(path)的第二个元素
5.path.split(path)的第二个元素。
6.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
7.path.isabs(path) 如果path是绝对路径,返回True
8.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
9.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
10.path.join(path1[, path2[, …]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
11.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间
12.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
13.path.getsize(path) 返回path的大小
os.stat(‘path/filename’) 获取文件/目录信息 的结构说明
st_mode: inode 保护模式
st_ino: inode 节点号。
st_dev: inode 驻留的设备。
st_nlink: inode 的链接数。
st_uid: 所有者的用户ID。
st_gid: 所有者的组ID。
st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
st_atime: 上次访问的时间。
st_mtime: 最后一次修改的时间。
st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)
sys模块是与python解释器交互的一个接口
1.argv[0]:argv[0]=脚本名、argv[0]=脚本名后第一个参数、argv[0]=脚本名后第二个参数…
2.modules:返回导入模块的字典
3.exit(a):程序中间退出,a=0时,表示正常退出
4.getrecursionlimit():获取最大递归层数
5.setrecursionlimit(a):设置最大递归层数
6.getdefaultencoding():获取系统当前编码
7.setdefaultencoding():设置系统默认编码
8.getfilesystemencoding():获取系统文件编码方式
9.platform:获取当前系统平台
1.序列化:将内存中的数据转换成字节,用以保存在文件或通过网络传输,称为序列化过程
2.反序列化:从文件中或网络中获取数据,转换成内存中原来的数据类型,称为反序列化过程
3.序列化的目的:以某种存储形式使自定义对象持久化;将对象从一个地方传递到另一个地方;使程序更具维护性。
1.json模块:将数据转换成字符串,用于储存或网络传输
进行序列化时,Python类型与Json类型的转换关系如下表所示:
进行反序列化时,Json类型与Python类型的转换关系如下:
2.pickle模块:用于python特有的类型 和 python的数据类型间进行转换
1.dumps(a):把指定对象a转换成json格式的字符串
2.dump(a,b):把制定对象a转换成json格式字符串写入b句柄对应文件
3.loads(a):把指定对象a转换成Python格式的数据类型
4.loads(a,b):从b句柄对应的文件读出json格式的字符串转换成Python对象
#导入json模块和pickle模块
import json
import pickle
dic = {
'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic1 = json.dumps(dic) #序列化:将一个字典转换成一个字符串
print(type(str_dic1), str_dic1)
# {"k3": "v3", "k1": "v1", "k2": "v2"}
str_dic2 = pickle.dumps(dic)
print(type(str_dic2), str_dic2)
# b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x00\x00\x00k2q\x03X\x02\x00\x00\x00v2q\x04X\x02\x00\x00\x00k3q\x05X\x02\x00\x00\x00v3q\x06u.'
dic1 = json.loads(str_dic1) #反序列化:将一个字符串格式的字典转换成一个字典
print(type(dic1), dic1)
# {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
dic2 = pickle.loads(str_dic2)
print(type(dic2), dic2)
# {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
1.json模块:
1>.不是所有的数据类型都可以序列化,结果是字符串
2>.不能多次对同一文件序列化
3>.json数据可以跨平台
2.pickle模块:
1>.所有Python类型都能序列化,结果是字节串
2>.可以多次对同一文件序列化
3>.不能跨平台
shelve是python提供给我们的序列化工具,只提供了一个open方法,是用key来访问的,使用起来和字典类似。
#导入shelve模块
import shelve
f = shelve.open('shelve_file')
f['key'] = {
'int': 20, 'float': 9.5, 'string': 'Sample data'}
#直接对文件句柄操作,就可以存入数据
f.close()
import shelve
f1 = shelve.open('shelve_file')
existing = f1['key']
#取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
f1.close()
print(existing)
1.hash:hash是一种算法(不同的hash算法只是复杂度不一样),hash算法就像一座工厂,工厂接收你送来的原材料,用m.update()为工厂运送原材料,经过加工返回的产品就是hash值;
2.Python3里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法,该算法接受传入的内容,经过运算得到一串hash值;
3.hash值的特点(hash值/产品有三大特性:):
3.1 只要传入的内容一样,得到的hash值必然一样
3.2 不能由hash值返解成内容
3.3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的
#导入hashlib模块
import hashlib
obj = hashlib.md5() #构造一个hashlib的对象
print(obj) #
#导入hashlib模块
import hashlib
obj = hashlib.md5()
res = obj.update("aabbccdd".encode("utf-8"))#加密处理
print(res, type(res))#update无返回值
#导入hashlib模块
import hashlib
obj = hashlib.md5()
obj.update("aabbccdd".encode("utf-8"))#加密处理
res = obj.hexdigest()#获取加密后的字符串
print(res, type(res))#bf3b2290e229da2ba272a81c602ea88d
#导入hashlib模块
import hashlib
salt = 'salt'#设置‘盐’
obj = hashlib.md5(salt.encode('utf-8'))#加‘盐’处理
obj.update("aabbccdd".encode("utf-8"))#加密处理
res = obj.hexdigest()#获取加密后的字符串
print(res, type(res))#32a08f2db87c3bf6b3e61eeeee69377b
#导入hashlib模块
import hashlib
def get_md5(data):
salt = 'salt'#设置‘盐’
obj = hashlib.md5(salt.encode('utf-8'))#加‘盐’处理
obj.update("aabbccdd".encode("utf-8"))#加密处理
res = obj.hexdigest()#获取加密后的字符串
return res
val = get_md5('abc')
print(val)#32a08f2db87c3bf6b3e61eeeee69377b
import hashlib
USER_LIST = []
def get_md5(data):
obj = hashlib.md5("12:;idrsicxwersdfsaersdfsdfresdy54436jgfdsjdxff123ad".encode('utf-8'))
obj.update(data.encode('utf-8'))
result = obj.hexdigest()
return result
def register():
print('**************用户注册**************')
while True:
user = input('请输入用户名:')
if user == 'N':
return
pwd = input('请输入密码:')
temp = {
'username':user,'password':get_md5(pwd)}
USER_LIST.append(temp)
def login():
print('**************用户登陆**************')
user = input('请输入用户名:')
pwd = input('请输入密码:')
for item in USER_LIST:
if item['username'] == user and item['password'] == get_md5(pwd):
return True
register()
result = login()
if result:
print('登陆成功')
else:
print('登陆失败')
collections模块包含了一些特殊的容器,针对Python内置的容器,例如list、dict、set和tuple,提供了另一种选择
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等
Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。
#导入collections模块
from collections import *
str = 'hello python'
c = Counter(str)
print(c)#Counter({'h': 2, 'l': 2, 'o': 2, 'e': 1, ' ': 1, 'p': 1, 'y': 1, 't': 1, 'n': 1})
print(c['l'])#2
print(c.most_common(2))#[('h', 2), ('l', 2)]
1.element():返回一个迭代器,每个元素重复的次数为它的数目,顺序是任意的顺序,如果一个元素的数目少于1,那么elements()就会忽略它;
#导入collections模块
from collections import *
str = 'hello python'
c = Counter(str)
m = c.elements()#返回一个迭代器
print(list(m))#['h', 'h', 'e', 'l', 'l', 'o', 'o', ' ', 'p', 'y', 't', 'n']
2.most_common(n):返回一个列表,包含counter中n个最大数目的元素,如果忽略n或者为None,most_common()将会返回counter中的所有元素,元素有着相同数目的将会以任意顺序排列;
#导入collections模块
from collections import *
str = 'hello python'
c = Counter(str)
m = c.most_common(2)#返回一个列表,包含counter中2个最大数目的元素
print(m)#[('h', 2), ('l', 2)]
3.subtract():从一个可迭代对象中或者另一个映射(或counter)中,元素相减,类似于dict.update(),但是subtracts 数目而不是替换它们,输入和输出都有可能为0或者为负;
#导入collections模块
from collections import *
a = Counter(a = 4, b = 2, c = 0, d = -2)
b = Counter(a = 1, b = 2, c = -3, d = 4)
a.subtract(b)#a-b
print(a)#Counter({'a': 3, 'c': 3, 'b': 0, 'd': -6})
4.update():从一个可迭代对象中或者另一个映射(或counter)中所有元素相加,类似于dict.upodate,是数目相加而非替换它们,另外,可迭代对象是一个元素序列,而非(key,value)对构成的序列
#导入collections模块
from collections import *
a = Counter(a = 4, b = 2, c = 0, d = -2)
b = Counter(a = 1, b = 2, c = -3, d = 4)
a.update(b)#a+b
print(a)#Counter({'a': 5, 'b': 4, 'd': 2, 'c': -3})
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
1.append(x), 将x添加到deque的右侧;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 8, 10]
de = deque(l1)
de.append('x')#将x添加到deque的右侧
print(de)#deque([1, 3, 5, 8, 10, 'x'])
2.appendleft(x), 将x添加到deque的左侧;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 8, 10]
de = deque(l1)
de.appendleft('x')#将x添加到deque的左侧
print(de)#deque(['x', 1, 3, 5, 8, 10])
3.clear(), 将deque中的元素全部删除,最后长度为0;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 8, 10]
de = deque(l1)
de.clear()#将deque中的元素全部删除
print(de)#deque([])
4.count(x), 返回deque中元素等于x的个数;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 8, 10]
de = deque(l1)
m = de.count(3)#返回deque中元素等于3的个数
print(m)#1
5.extend(iterable), 将可迭代变量iterable中的元素添加至deque的右侧;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 8, 10]
de = deque(l1)
de.extend([2,6,9])#将可迭代变量iterable中的元素添加至deque的右侧
print(de)#deque([1, 3, 5, 8, 10, 2, 6, 9])
6.extendleft(iterable), 将变量iterable中的元素添加至deque的左侧,往左侧添加序列的顺序与可迭代变量iterable中的元素相反;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 8, 10]
de = deque(l1)
de.extendleft([2,6,9])#将变量iterable中的元素添加至deque的左侧
print(de)#deque([9, 6, 2, 1, 3, 5, 8, 10])
7.pop(), 移除和返回deque中最右侧的元素,如果没有元素,将会报出IndexError;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 8, 10]
de = deque(l1)
de.pop()# 移除和返回deque中最右侧的元素
print(de)#deque([1, 3, 5, 8])
8.popleft(), 移除和返回deque中最左侧的元素,如果没有元素,将会报出IndexError;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 8, 10]
de = deque(l1)
de.popleft()# 移除和返回deque中最左侧的元素
print(de)#deque([3, 5, 8, 10])
9.remove(value), 移除第一次出现的value,如果没有找到,报出ValueError;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 5, 8, 10]
de = deque(l1)
de.remove(5)# 移除第一次出现的value
print(de)#deque([1, 3, 5, 8, 10])
10.reverse(), 反转deque中的元素,并返回None;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 5, 8, 10]
de = deque(l1)
de.reverse()# 反转deque中的元素
print(de)#deque([10, 8, 5, 5, 3, 1])
11.rotate(n), 从右侧反转n步,如果n为负数,则从左侧反转,d.rotate(1)等于d.appendleft(d.pop());
#导入collections模块
from collections import *
l1 = [1, 3, 5, 5, 8, 10]
de = deque(l1)
de.rotate(3)# 从右侧反转n步,如果n为负数,则从左侧反转
print(de)#deque([5, 8, 10, 1, 3, 5])
12.maxlen, 只读的属性,deque的最大长度,如果无解,就返回None;
#导入collections模块
from collections import *
l1 = [1, 3, 5, 5, 8, 10]
de = deque(l1)#只读的属性,deque的最大长度
print(de.maxlen)#None
defaultdict是内置数据类型dict的一个子类,基本功能与dict一样,只是重写了一个方法missing(key)和增加了一个可写的对象变量default_factory,实现了带默认值功能的字典。
1.defaultdict类就像是一个dict,但是它是使用一个类型(str、int、list、dict或函数)或者不带参数的可调用函数来初始化
#导入defaultdict模块
from collections import *
dic = defaultdict(list)
print(dic)#defaultdict(, {})
def zero():
return 'm'
dd = defaultdict(zero)
print(dd)
print(dd['ppo'])#m
2.defaultdict类的初始化函数接受一个类型作为参数,当所访问的键不存在的时候,可以实例化一个值作为默认值:
#导入defaultdict模块
from collections import *
dic = defaultdict(int, {
'ppo': 123})
print(dic)#defaultdict(, {})
print(dic['ppo'])#123
3.利用collections.defaultdict来解决最初的单词统计问题,代码如下:
#导入defaultdict模块
from collections import *
strings = ('puppy', 'kitten', 'puppy', 'puppy',
'weasel', 'puppy', 'kitten', 'puppy')
counts = defaultdict(lambda: 0) # 使用lambda来定义简单的函数
for s in strings:
counts[s] += 1
print(counts)#defaultdict( at 0x0000022455C5C1E0>, {'puppy': 5, 'kitten': 2, 'weasel': 1})
1.查看__missing__()这个方法
>>> from collections import defaultdict
>>> print defaultdict.__missing__.__doc__
__missing__(key) # Called by __getitem__ for missing key; pseudo-code:
if self.default_factory is None: raise KeyError(key)
self[key] = value = self.default_factory()
return value
2.如果default_factory属性为None,就报出以key作为遍历的KeyError异常
#导入defaultdict模块
from collections import *
m = defaultdict(None)
print(m['s'])#报异常
3.如果default_factory不为None,就会向给定的key提供一个默认值,这个值插入到字典中,并返回;
4.如果调用default_factory报出异常,这个异常在传播时不会改变;
5.这个方法是当要求的key不存在时,dict类中的getitem()方法所调用,无论它返回或者报出什么,最终返回或报出给getitem();
6.只有getitem()才能调用missing(),这意味着,如果get()起作用,如普通的词典,将会返回None作为默认值,而不是使用default_factory;
7.default_factory, 这个属性用于missing()方法,使用构造器中的第一个参数初始化;
生成可以使用名字来访问元素内容的tuple。
1.namedtuple是一个 工厂函数,定义在python标准库的collections模块中,使用此函数可以创建一个可读性更强的元组
2.namedtuple函数所创建(返回)的是一个 元组的子类(python中基本数据类型都是类,且可以在buildins模块中找到)
3.namedtuple函数所创建元组,中文名称为 具名元组
4.在使用普通元组的时候,我们只能通过index来访问元组中的某个数据
5.使用具名元组,我们既可以使用index来访问,也可以使用具名元组中每个字段的名称来访问
6.值得注意的是,具名元组和普通元组所需要的内存空间相同,所以 不必使用性能来权衡是否使用具名元组
#导入namedtuple模块
from collections import *
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
print(p.x, p.y)#1 2
OrderedDict是对字典类型的补充,他记住了字典元素添加的顺序,但Python3.6版本后普通字典也变成有序字典了。
ConfigParser 是用来读取配置文件的包。配置文件的格式如下:中括号“[ ]”内包含的为section。section 下面为类似于key-value 的配置内容。
括号“[ ]”内包含的为section。紧接着section 为类似于key-value 的options 的配置内容。
配置文件ini:
[db]
db_host = 127.0.0.1
db_port = 88
db_user = root
db_pass = root
host_port = 88
[concurrent]
thread = 10
processor = 20
#导入configparser模块
import configparser
config = configparser.ConfigParser()#初始化对象
config.read("ini", encoding="utf-8")#读取ini文件
1、获取所用的section节点
# 获取所用的section节点
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
print(config.sections())
#运行结果
# ['db', 'concurrent']
2、获取指定section 的options。即将配置文件某个section 内key 读取到列表中:
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
r = config.options("db")
print(r)
#运行结果
# ['db_host', 'db_port', 'db_user', 'db_pass', 'host_port']
3、获取指点section下指点option的值
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
r = config.get("db", "db_host")
# r1 = config.getint("db", "k1") #将获取到值转换为int型
# r2 = config.getboolean("db", "k2" ) #将获取到值转换为bool型
# r3 = config.getfloat("db", "k3" ) #将获取到值转换为浮点型
print(r)
#运行结果
# 127.0.0.1
4、获取指点section的所用配置信息
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
r = config.items("db")
print(r)
#运行结果
#[('db_host', '127.0.0.1'), ('db_port', '69'), ('db_user', 'root'), ('db_pass', 'root'), ('host_port', '69')]
5、修改某个option的值,如果不存在则会出创建
#修改某个option的值,如果不存在该option 则会创建
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
config.set("db", "db_port", "69") #修改db_port的值为69
config.write(open("ini", "w"))
print(config.get('db', "db_port"))
运行结果
#69
6、检查section或option是否存在,bool值
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
bl1 = config.has_section('db') #是否存在该section
bl2 = config.has_option("section", "ss") #是否存在该option
print(bl1)
print(bl2)
运行结果
#True
#False
7、添加section 和 option
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
if not config.has_section("default"): # 检查是否存在section
config.add_section("default")
if not config.has_option("default", "db_host"): # 检查是否存在该option
config.set("default", "db_host", "1.1.1.1")
config.write(open("ini", "w"))
运行结果(ini文件)
[db]
db_host = 127.0.0.1
db_port = 69
db_user = root
db_pass = root
host_port = 88
[concurrent]
thread = 10
processor = 20
[default]
db_host = 1.1.1.1
8、删除section 和 option
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
config.remove_section("default") #整个section下的所有内容都将删除
config.write(open("ini", "w"))
运行结果(ini文件)
[db]
db_host = 127.0.0.1
db_port = 69
db_user = root
db_pass = root
[concurrent]
thread = 10
processor = 20
9、写入文件
以下的几行代码只是将文件内容读取到内存中,进过一系列操作之后必须写回文件,才能生效。
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
写回文件的方式如下:(使用configparser的write方法)
config.write(open("ini", "w")
Python 中的 logging 模块可以让你跟踪代码运行时的事件,当程序崩溃时可以查看日志并且发现是什么引发了错误。Log 信息有内置的层级——调试(debugging)、信息(informational)、警告(warnings)、错误(error)和严重错误(critical)。你也可以在 logging 中包含 traceback 信息。不管是小项目还是大项目,都推荐在 Python 程序中使用 logging
logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:
1.可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
2.print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出;
1.当你运行一个 Python 脚本时,你可能想要知道脚本的哪个部分在执行,并且监视变量的当前值
2.因为代码需要经历开发、调试、审查、测试或者上线等不同阶段,在开发时你想要打印的信息类型可能和上线后你想看到的信息类型完全不同,也就是说,在“测试”时,你可能只想看警告和错误信息,然而在“调试”时,你可能还想看到跟调试相关的信息,如果你还想打印出使用的模块以及代码运行的时间,那么你的代码很容易变得混乱,使用logging模块,这些问题就能很容易地解决
1.控制信息层级,仅记录需要的信息。
2.控制显示或者保存日志的时机。
3.使用内置信息模板控制日志格式。
4.知晓信息来自于哪个模块
1.配置logging基本的设置,然后在控制台输出日志:
#导入logging模块
import logging
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")
#运行结果:
# 2020-08-31 23:15:37,823 - __main__ - INFO - Start print log
# 2020-08-31 23:15:37,823 - __main__ - WARNING - Something maybe fail.
# 2020-08-31 23:15:37,823 - __main__ - INFO - Finish
logging中可以选择很多消息级别,如debug、info、warning、error以及critical。通过赋予logger或者handler不同的级别,开发者就可以只输出错误信息到特定的记录文件,或者在调试时只记录调试信息。
例如,我们将logger的级别改为DEBUG,再观察一下输出结果:
#导入logging模块
import logging
logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")
#运行结果:
# 2020-08-31 23:19:39,580 - __main__ - INFO - Start print log
# 2020-08-31 23:19:39,580 - __main__ - DEBUG - Do something
# 2020-08-31 23:19:39,580 - __main__ - WARNING - Something maybe fail.
# 2020-08-31 23:19:39,580 - __main__ - INFO - Finish
2.简单配置
import logging
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
运行结果:
# WARNING:root:warning message
# ERROR:root:error message
# CRITICAL:root:critical message
默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。
3.logging有 6 个不同层次的日志级别,可以将给定的 logger 配置为这些级别:
FATAL:致命错误
DEBUG:详细信息,用于诊断问题。Value=10。
INFO:确认代码运行正常。Value=20。
WARNING:意想不到的事情发生了,或预示着某个问题。但软件仍按预期运行。Value=30。
ERROR:出现更严重的问题,软件无法执行某些功能。Value=40。
CRITICAL:严重错误,程序本身可能无法继续运行。Value=50。
3.logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为
3.1可用参数:
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参数会被忽略。
3.2format参数中可能用到的格式化串:
%(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用户输出的消息
1.将日志写入到文件
设置logging,创建一个FileHandler,并对输出消息的格式进行设置,将其添加到logger,然后将日志写入到指定的文件中:
#导入logging模块
import logging
#提供应用程序可直接使用的接口
logger = logging.getLogger(__name__)
#单对文件流设置某个级别
logger.setLevel(level = logging.INFO)
#日志输出到log.txt文件
handler = logging.FileHandler("log.txt")
#单对文件流设置某个级别
handler.setLevel(logging.INFO)
#指定日志显示格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
#把logger添加到log.txt中
logger.addHandler(handler)
#添加的消息
logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")
#log.txt中日志数据为,
#2016-10-09 19:01:13,263 - __main__ - INFO - Start print log
#2016-10-09 19:01:13,263 - __main__ - WARNING - Something maybe fail.
#2016-10-09 19:01:13,263 - __main__ - INFO - Finish
logging库提供了多个组件:Logger、Handler、Filter、Formatter
1.Logger对象提供应用程序可直接使用的接口
2.Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法
3.Formatter指定日志显示格式
4.logger.setLevel(logging.Debug)设置级别,当然,也可以通过xxx.setLevel(logging.Debug)单对文件流设置某个级别
2.将日志同时输出到屏幕和日志文件
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
console = logging.StreamHandler()
console.setLevel(logging.INFO)
logger.addHandler(handler)
logger.addHandler(console)
logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")
可以发现,logging有一个日志处理的主对象,其他处理方式都是通过addHandler添加进去,logging中包含的handler主要有如下几种:
1.StreamHandler:logging.StreamHandler;日志输出到流,可以是sys.stderr,sys.stdout或者文件
2.FileHandler:logging.FileHandler;日志输出到文件
3.BaseRotatingHandler:logging.handlers.BaseRotatingHandler;基本的日志回滚方式
4.RotatingHandler:logging.handlers.RotatingHandler;日志回滚方式,支持日志文件最大数量和日志文件回滚
2.TimeRotatingHandler:logging.handlers.TimeRotatingHandler;日志回滚方式,在一定时间区域内回滚日志文件
6.SocketHandler:logging.handlers.SocketHandler;远程输出日志到TCP/IP sockets
7.DatagramHandler:logging.handlers.DatagramHandler;远程输出日志到UDP sockets
8.SMTPHandler:logging.handlers.SMTPHandler;远程输出日志到邮件地址
9.SysLogHandler:logging.handlers.SysLogHandler;日志输出到syslog
10.NTEventLogHandler:logging.handlers.NTEventLogHandler;远程输出日志到Windows NT/2000/XP的事件日志
11.MemoryHandler:logging.handlers.MemoryHandler;日志输出到内存中的指定buffer
HTTPHandler:logging.handlers.HTTPHandler;通过"GET"或者"POST"远程输出到HTTP服务器
re模块是python独有的匹配字符串的模块,该模块中提供的很多功能是基于正则表达式实现的,而正则表达式是对字符串进行模糊匹配,提取自己需要的字符串部分,他对所有的语言都通用。注意:
1.re模块是python独有的
2.正则表达式所有编程语言都可以使用
3.re模块、正则表达式是对字符串进行操作
因为,re模块中的方法大都借助于正则表达式,故先学习正则表达式。
1.正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。
2.正则就是用来描述一类事物的规则。
3.在Python中,它内嵌在Python中,并通过 re 模块实现。
4.正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
1.检测一个输入的字符串是否合法 – web开发项目 表单验证
用户输入一个内容的时候,我们要提前做检测
能够提高程序的效率并且减轻服务器的压力
2.从一个大文件中找到所有符合规则的内容 – 日志分析\爬虫
能够高效的从一大段文字中快速找到符合规则的内容
1、字符组
在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
[0123456789] | 8 | True | 在一个字符组里枚举合法的所有字符,字符组里的任意一个字符和"待匹配字符"相同都视为可以匹配 |
[0123456789] | a | False | 由于字符组中没有"a"字符,所以不能匹配 |
[0-9] | 7 | True | 也可以用"-"表示范围,[0-9]就和[0123456789]是一个意思 |
[a-z] | m | True | 同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示 |
[A-Z] | M | True | [A-Z]就表示所有的大写字母 |
[0-9a-fA-F] | z | True | 可以匹配数字,大小写形式的a~f,用来验证十六进制字符 |
2、字符
元字符 | 匹配内容 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
\b | 匹配一个单词的结尾 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结尾 |
\W | 匹配非字母或数字或下划线 |
\D | 匹配非数字 |
\S | 匹配非空白符 |
a | b |
() | 匹配括号内的表达式,也表示一个组 |
[…] | 匹配字符组中的字符 |
[^…] | 匹配除了字符组中字符的所有字符 |
3、量词
量词 | 用法说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
1、. ^ $
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
a. | abacad | abacad | 匹配所有"a."的字符 |
^a. | abacad | ab | 只从开头匹配"a." |
a.$ | abacad | ad | 只匹配结尾的"a.$" |
2、* + ? { }
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
a.? | abefacgad | ab、ac、ad | ?表示重复零次或一次,即只匹配"a"后面一个任意字符。 |
a.* | abefacgad | abefacgad | *表示重复零次或多次,即匹配"a"后面0或多个任意字符。 |
a.+ | abefacgad | abefacgad | +表示重复一次或多次,即只匹配"a"后面1个或多个任意字符。 |
a.{1,2} | abefacgad | abe、acg、ad | {1,2}匹配1到2次任意字符。 |
a.*? | abefacgad | a、a、a | 惰性匹配,上面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配 |
3、字符集[][^]
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
a[befcgd]* | abefacgad | abef、acg、d | 表示匹配"a"后面[befcgd]的字符任意次 |
a[^f]* | abefacgad | abe、acg、ad | 表示匹配一个不是"f"的字符任意次 |
[\d] | 412a3bc | 4、1、2、3 | 表示匹配任意一个数字,匹配到4个结果 |
[\d]+ | 412a3bc | 412、3 | 表示匹配任意个数字,匹配到2个结果 |
4、分组 ()与 或 |[^]
身份证号码是一个长度为15或18个字符的字符串,如果是15位则全部由数字组成,首位不能为0;如果是18位,则前17位全部是数字,末位可能是数字或x,下面我们尝试用正则来表示:
错误1:范围大于实际范围
#导入re模块
import re
#以1-9开头的数字,0-9或x结尾的字符左边的13-16位
r1 = '^[1-9]\d{13,16}[0-9x]$'
print(re.findall(r1, '652801199102104457'))
print(re.findall(r1, '65280119910210445'))
#结论:
#存在bug,长度为15-17位的数字也能被匹配
错误2:分组运用有问题
#导入re模块
import re
#以1-9开头的数字,0-9或x结尾的字符左边的13-16位
r1 = r'^[1-9]\d{14}(\d{2}[0-9x])$'
print(re.findall(r1, '6528011991021'))
#存在bug,只匹配了括号内的内容
正确方式:
位数 | 要求 | 正则表达式 |
---|---|---|
1 | 1-9的数字 | [1-9] |
2-6 | 0-9的数字 | \d{5} |
7-10 | 年份:1或2开头,剩下三位随意数字 | [12]\d{3} |
11-12 | 月份:01-12 | (0[1-9]或1[012]) |
13-14 | 日期:0开头接1-9或1、2开头接0-9或3开头接0 | 0[1-9]或[12][0-9]或3[01] |
15-17 | 数字0-9 | d{3} |
18 | 数字0-9、x或X | [0-9xX] |
最终代码:
#导入re模块
import re
r=r'^([1-9]\d{5}[12]\d{3}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])\d{3}[0-9xX])$'
lis = re.findall(r, '350124198310131229')
res = list(lis[0])[0].split(',')[0]
print(res)
5、转义符
在正则表达式中,有很多有特殊意义的是元字符,比如\n和\s等,如果要在正则中匹配正常的"\n"而不是"换行符"就需要对""进行转义,变成’\’;
#导入re模块
import re
r = '\n'
lis = re.findall(r, '\n')
print(lis)
st = "111" + lis[0] + '222'
print(st)
#运行结果:
# 111
# 222
结论:
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
\n | \n | False | 因为在正则表达式中\是有特殊意义的字符,所以要匹配\n本身,用表达式\n无法匹配 |
#导入re模块
import re
r = '\\\\n'
lis = re.findall(r, '\\n')
print(lis)
st = "111" + lis[0] + '222'
print(st)
#运行结果:
#['\\n']
#111\n222
结论:
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
\ \ \ \n | \ \n | True | 如果在python中,字符串中的’‘也需要转义,所以每一个字符串’'又需要转义一次 |
#导入re模块
import re
r = r'\\n'
lis = re.findall(r, r'\n')
print(lis)
st = "111" + lis[0] + '222'
print(st)
#运行结果:
#['\\n']
#111\n222
结论:
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
r’\n’ | r’\n’ | True | 在字符串之前加r,让整个字符串不转义 |
6、贪婪匹配
在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
<.*> |
你可能感兴趣的:(Python模块,python,编程语言,事件模块) |