collections---------------------------------------->扩展数据类型
re-------------------------------------------------->正则相关操作,正则 匹配字符串
time----------------------------------------------->时间相关 三种格式:时间戳,结构化时间,格式化时间
random------------------------------------------->随机数相关:生成验证码
os------------------------------------------------->和操作系统相关
sys------------------------------------------------>和pytho解释器交互的
序列化-------------------------------------------->json.json 通用数据结构,在python里表现的是字典和列表
pickle在python里专用的,可以对任何数据类型做序列化,结果是byte
shelve 只提供一个open方法,操作像字典
一:正则表达式
定义:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符,及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
元字符 匹配内容
. 匹配换行符以外的
任意字符
\w 匹配数字子母下滑线
\W 匹配非数字字母下滑线
\s 匹配任意空白字符
\S 匹配任意非任意字符
\d 匹配数字
\D 匹配非数字
\n 匹配一个换行符
\t 匹配一个制表符
\b 匹配一个单词结尾
^ 匹配一个字符串的开始
$ 匹配字符串的结尾
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示一个组
[.......] 匹配字符组中的字符
2:量词
量词 用法说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n次到m次
3:前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配
4:.^$
正则 待匹配字符 匹配结果 说明
天. 天空天下天上人间 天空天下天上人间 匹配所有“天.”的字符
^天 天空天下天上人间 天空 只从开头匹配“天”
天$ 天空天下天上人间 天上人间 只匹配结尾的“海$”
5:*+?{}
正则 待匹配字符 匹配结果 说明
李? 李杰和李莲英和李二棍子 李杰 李莲 李二 匹配”李“后面一个任意字符
李* 李杰和李莲英和李二棍子 李杰和李莲英和李二棍子 匹配“李”后面0个或多个任意字符
李+ 李杰和李莲英和李二棍子 李杰和李莲英和李二棍子 匹配“李”字后面一个或多个字符
李{1,2} 李杰和李莲英和李二棍子 李杰和
李莲英
李二棍子 匹配“李”字后面1到2次任意字符
6:惰性匹配
正则 待匹配字符 匹配结果 说明
李*^ 李杰和李莲英和李二棍子 李杰 李莲 李二 加?号变惰性匹配
7:字符集[] [^]
正则 待匹配字符 匹配结果 说明
李[杰莲英二棍子]* 李杰和李莲英和李二棍子 李杰 匹配"李"字后面李[杰莲英二棍子]*的字符的任意次数
李莲英
李二棍子
李[^和]* 李杰和李莲英和李二棍子 李杰 李莲英 李二棍子 匹配一个不是“和”的字符任意次
[\d] 456bdha3 4 5 6 3 匹配任意一个数字,匹配到四个结果
[\d]+ 456bdha3 456
3 匹配任意个数字,匹配到2个结果
8:分组()与或| [^]
正则 待匹配字符 匹配结果 说明
^[1-9]\d{13,16}[0-9x]$ 110101198001017032 110101198001017032 匹配一个正确的身份证号
^[1-9]\d{14}(\d{2}[0-9x])?$ 110101198001017032 False 现在不会匹配错误的身份证号了 ()表示分组,将\d{2}[0-9x] 分成一组,就可以整体约束他们出现的次数为0-1次
^([1-9]\d{16}[0-9x]|[1-9]\d{14})$ 110101198001017032 110105199812067023 表示先匹配[1-9]\d{16}[0-9x]如果没有匹配上就匹配[1-9]\d{14}
9:转义符
则 | 待匹配字符 | 匹配 结果 | 说明 |
\d | \d | False | 因为在正则表达式中\是有特殊意义的字符,所以要匹配\d本身,用表达式\d无法匹配 |
\\d | \d | True | 转义\之后变成\\,即可匹配 |
"\\\\d" | '\\d' | True | 如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次 |
r'\\d' | r'\d' | True | 在字符串之前加r,让整个字符串不转义 |
10:贪婪匹配
贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配
正则 待匹配字符 匹配结果 说明
<*> <script>......<script> <script>......<script> 默认贪婪匹配模式,会匹配尽量长的字符串
<*?> r'\d' <script>
<script> 加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串
11:几个常用的非贪婪匹配pattern
*?重复任意次,但尽可能少重复
+?重复1次或多次,但尽量少重复
??重复0次或一次,但尽可能少重复
{n,m}重复n到m次,但尽量少重复
{n,}?重复n次以上,但尽量少重复
. 是任意字符 * 是取 0 至 无限长度 ? 是非贪婪模式。 何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在: .*?x 就是取前面任意长度的字符,直到一个x出现
12:re模块下的常用方法
二:模块
常见的场景:一个模块就是你一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀
1使用python编写的代码(.py文件)
2已被编译为共享库或DELL的c或c++扩展
3包好一组模块的包
4使用c编写并链接到python解释器的内置模块
为何要使用模块?
如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。
随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用。
1:re模块
import re
phone_number=input("请输入您的手机号:")
if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):print("您输入的手机号合法!")
else:print("您输入的手机号不合法")
re 模块下的常用方法
#! usr/bin/env python
# -*- coding: utf-8 -*-
#输入手机号是否合法
# import re
# phone_number=input("请输入您的手机号:")
# if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):
# print("您输入的手机号合法!")
# else:
# print("您输入的手机号不合法")
#执行结果 请输入您的手机号:18740920463#您输入的手机号合法!
#re模块下的常用方法# 返回所有满足匹配的条件,放在列表里
# import re
# ret = re.findall('a','eva egon yuan')
# print(ret)#只找一个
# ret = re.search('a','eva egon yuan').group()#---------->search找到所有的a函数会在字符串内查找模式匹配,只
# print(ret) #结果:a # 到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以#通过调用group()方法得匹配的字符串,如果字符串没有匹配,则返回None。#只找开头
# import re
# ret = re.match('a','abc').group()#--------------------->match在字符串开始处进行查找
# print(ret)#结果a #同seach,不过尽在字符串开始处进行匹配。
# string = '4653fhfhfg4547'
# ret = re.findall('\d+',string) #找全部
# ret = re.search('\d+',string) #找一个
# ret = re.match('\d+',string).group() # 必须在字符串的开头,
# print(ret)#分割
# import re
# ret = re.split('[ab]','abcd')#先按'a'进行分割得到''和'bcd',再对'和'bcd'分别按'b'分割
# print(ret)#替换
# import re
# ret = re.sub('\d','H','eva3egon4yuan4',1)#将数字替换成'H',参数1,表示只替换一个
# print(ret)#匹配3个数字-------->将正则表达式,编译成一个正则表达对象
# import re
# obj=re.compile('\d{3}')#将正则表达式编译成为一个正则表达对象,匹配3个数字
# ret = obj.search('abc123qqqqqqq')#正则表达式对象调用search,参数为待匹配的字符串
# print(ret.group())# import re
# ret = re.finditer('\d','ds3sy4784a')#finditer返回一个存放匹配结果的迭代器
# print(ret)
# print(next(ret).group())#查看第一个结果
# print(next(ret).group())#查看第二个结果
# print([i.group()for i in ret])#查看剩余的左右结果#findall的优先级查询
# import re
# ret = re.findall('www.(beidu|oldboy).com','www.oldboy.com')
# print(ret)#findall会优先把匹配结果组的内容返回,如果想要匹配结果取消权限即可
# ret = re.findall('www.(?:beidu|oldboy).com','www.oldboy.com')
# print(ret)#spilt的优先级查询
# import re
# ret = re.split('\d+','eva3yuan4yuan')#没有匹配所有的项
# print(ret)
# ret = re.split('(\d+)','eva3egon4yuan')#加()匹配所有的项
# print(ret)
collections模块
1:namedtupe:生成可以使用名字来访问的元素tupe
namedtupe模块
#tuple可以表示不变集合,表示坐标
from collections import namedtuple
point = namedtuple('point',['x','y'])
p=point(1,2)
print(p.x)
print(p.y)
#用坐标和半径表示一个圆
# from collections import namedtuple
# s=namedtuple('s',['x','y','r'])
# q = s(1,2,3)
# print(q)
2:deque:双端队列,可以快速的从另外一侧追加和推出对象(为了高效实现插入和删除操作的双向列表,适合用于队列和栈:)
使用list存储数据时,按索引访问元素很快,但是插入和删除就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
from collections import deque
q= deque(['a','b','c'])
q.append('x')
q.appendleft('y')
print(q)
deque除了实现list的append()
和pop()
外,还支持appendleft()
和popleft()
,这样就可以非常高效地往头部添加或删除元素。
3:Counter:计数器,主要用来计数
Couter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的建值形式存储,其中元素作为key,
其计数作为va。计数值可以是任意的Interer(包括0和负数)。coun类和其他语言的bag或multisets相似。
#Counter
from collections import Counter
c=Counter('cabywuhqsijhbcdjshcbcdnjxchbcdjch')
print(c)
#其他详细内容 http://www.cnblogs.com/Eva-J/articles/7291842.html
4:OrderedDict:有序字典
使用dic时,key是无序的。在对dic做迭代时,我们无法确定Key的顺序
如果要保持Key的顺序。
from collections import OrderedDict
d = dict([('a',1),('b',2),('c',3)])
print(d)#dict的Key是无序的
# 结果:'a': 1, 'b': 2, 'c': 3}
s=OrderedDict([('a',1),('b',2),('c',3)])
print(s)#OrderedDict的key是有序的
#结果OrderedDict([('a', 1), ('b', 2), ('c', 3)])
#OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:
from collections import OrderedDict
s=OrderedDict()
s['z']=1
s['x']=2
s['y']=3
s.keys()#按照插入的Key的顺序返回
print(s)
5:defaultict:带有默认值的字典
有如下值集合 [
11
,
22
,
33
,
44
,
55
,
66
,
77
,
88
,
99
,
90.
..],将所有大于
66
的值保存至字典的第 一个key中,将小于
66
的值保存至第二个key的值中。
即: {
'k1'
: 大于
66
,
'k2'
: 小于
66
}
values = [11,22,33,44,55,66,77,88,99,90]
my_dict = {}
for value in values:if values >66:if my_dict.has_key('k1'):my_dict['k1'].append(value)else:my_dict['k1'] = [value]else:if my_dict.has_key('k2'):my_dict['k2'].append(value)else:my_dict['k2'] = [value]
print(my_dict)
# from collections import defaultdict
# values = [11,22,33,44,55,66,77,88,99,90]
# my_dict = defaultdict(list)
# for value in values:
# if value>66:
# my_dict['k1'].append(value)
# else:
# my_dict['k2'].append(value)
# print(my_dict)
使用dic时,如果引用的key不存在,就会抛出keyError。如果key不存在,返回一个默认的值,就可以用defaultdict:
>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回默认值
'N/A'
时间模块
和时间有关系的我们就要用到时间模块。在使用模块之前,先导入这个模块。
常用方法:
1:time.sleep(sacs)
(线程)推迟指定的时间运行。单位为秒
2:time.time()
获取当前时间戳
表示时间的三种方式
时间戳-------元组(struct_time)----------格式化的时间字符串
(1)时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
(2)格式化的时间字符串(FormatString):‘1999-12-06’
python中的时间日期格式化符号:
两位数的年份表示(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 当前时区的名称
%% %号本身
(3)元组(struct_time):struct_time元组共有9个元素(年,月,日,时,分,秒,一年中的第几周,一年中第几天等)
引(Index) | 属性(Attribute) | 值(Values) |
---|---|---|
0 | tm_year(年) | 比如2011 |
1 | tm_mon(月) | 1 - 12 |
2 | tm_mday(日) | 1 - 31 |
3 | tm_hour(时) | 0 - 23 |
4 | tm_min(分) | 0 - 59 |
5 | tm_sec(秒) | 0 - 61 |
6 | tm_wday(weekday) | 0 - 6(0表示周日) |
7 | tm_yday(一年中的第几天) | 1 - 366 |
8 | tm_isdst(是否是夏令时) | 默认为-1 |
#! usr/bin/env python
# -*- coding: utf-8 -*-
# import time
#时间戳
# s=time.time()
# print(s)
#结果:1502189619.652187
#时间字符串
# s=time.strftime('%Y-%m-%d')
# print(s)
#结果:2017-08-08
#时间元组:localtime将一个时间戳转换为当前时区的struct_time
# import time
# time.localtime()
# time.struct_time(tm_year=2017,tm_mon=7,tm_mday=24,
# tm_hour=13,tm_min=59,tm_sec=37,
# tm_wday=0,tm_yday=205,tm_isdst=0
# )
时间戳是计算机能够识别的时间,时间字符是人能够看懂的时间,元组是用来操作时间的
几种格式之间的转换
1:时间戳--------->结构化时间
结构化时间--------->时间戳
#时间戳---->结构化时间
import time
# time.gmtime(时间戳)#UTC时间,与英国当地时间一致
# time.localtime(时间戳)#当地时间。例如我们现在在北京执行这个方法:与UTC时间相差8个小时,UTC时间+8小时=北京时间
# import time
# s=time.localtime(1500000000)
# print(s)
#结果:me.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
#Process finished with exit code 0#
# s=time.gmtime(1500000000)
# print(s)
#结果:time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
#结构化时间--->时间戳
#time.mktime(结构化时间)
# s=time.localtime(1500000000)
# g=time.mktime(s)
# print(g)
#结果:1500000000.0
2:结构化时间----------->字符串时间
字符串时间------------>结构化时间
#结构化时间------>字符串时间
import time
#time.strftime("格式定义","结构化时间")结构化时间参数,则实现当前时间
# s=time.strftime('%Y-%m-%d %X')
# print(s)
#结果:2017-08-08 20:07:00
# s=time.strftime("%Y-%m-%d ",time.localtime(1500000000))
# print(s)
#结果:2017-07-14
#字符串时间-------->结构化时间
#time.strptime(时间字符串,字符串对应格式)
# s=time.strptime("2017-03-16","%Y-%m-%d")
# print(s)
#结果:time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16,
# tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1)
# s=time.strptime("07/24/2017","%m/%d/%Y")
# print(s)
#结果:time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0,
# tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)
3:结构化时间--------->%a %b %d %H:%M: %S %Y
%a %b %d %H:%M: %S %Y-------------------> 结构化时间
结构化时间-------->%a %b %d %H:%M:%s %Y串
#time。asctime(结构化时间)如果不传参数,直接返回当前时间的格式化串
import time
# s=time.asctime(time.localtime(1500000000))
# print(s)
#结果:Fri Jul 14 10:40:00 2017
# q=time.asctime()
# print(q)
#%a %b %d %H:%M:%s %Y-------->结构化时间
#time.ctime(时间戳)如果不传参数,直接返回当前时间扽格式化串
# import time
# s=time.ctime()
# print(s)
# s=time.ctime(1500000000)
# print(s)
#结果:Wed Aug 9 15:29:20 2017
# Fri Jul 14 10:40:00 2017
rabdom模块
import random
#随机小数
# s=random.random() #大于0且小于1之间的小数
# print(s)
#结果:0.9186793553824543
# s=random.uniform(1,3) #大于1小于3的小数
# print(s)
#结果:2.3885376764938453
#随机整数
# s=random.randint(1,5) #大于等于 1且小于等于5之间的整数
# print(s)
# s=random.randrange(1,10,2) #大于等于1小于等于10的奇书
# print(s)
#随机选择一个返回
# s=random.choice([1,'23',[4,5]]) #1或者23或者[45]
# print(s)
#随机选择多个返回,返回的个数为函数的第二个参数
# s=random.sample([1,'23',[4,5]],2) #列表元素任意2个组合
# print(s)
#结果:[1, [4, 5]]
#打乱列表顺序
# item=[1,3,5,7,9]
# random.shuffle(item)
# print(item)
#结果:[1, 7, 5, 3, 9]
随机生成验证码
随机生成验证码
import random
def yanzhengma():code=' 'for i in range(5):num = random.randint(0,9)alf = chr(random.randint(65,90))anm = chr(random.randint(91,122))add = random.choice([num,alf,anm])code = "".join([code,str(add)])return code
print(yanzhengma())
os模块
os模块是与操作系统交互的一个接口
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","newname") 重命名文件/目录
os.stat('path/filename') 获取文件/目录信息
os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.popen("bash command) 运行shell命令,获取执行结果
os.environ 获取系统环境变量
os.path
os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小
'''
注意:os.stat('path/filename') 获取文件/目录信息 的结构说明
stat 结构: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)是创建时间(详细信息参见平台的文档)。
序列化模块
什么叫序列化——将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化
序列化的目的:
1:以某种存储形式使自定义对象持久化;
2:将对象从一个地方传递到另一个地方。
3:是程序更具维护性
json
json模块提供了四个功能:dumps,dump,loads,load
loads和dumps
port json
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串
print(type(str_dic),str_dic) #<class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
#注意,json转换完的字符串类型的字典中的字符串是由""表示的dic2 = json.loads(str_dic) #反序列化:将一个字符串格式的字典转换成一个字典
#注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(type(dic2),dic2) #<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
str_dic = json.dumps(list_dic) #也可以处理嵌套的数据类型
print(type(str_dic),str_dic) #<class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
list_dic2 = json.loads(str_dic)
print(type(list_dic2),list_dic2) #<class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
load和dump
import json
f = open('json_file','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f) #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
f.close()f = open('json_file')
dic2 = json.load(f) #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close()
print(type(dic2),dic2)
复制代码
pickle
json & pickle 模块
用于序列化的两个模块
- json,用于字符串 和 python数据类型间进行转换
- pickle,用于python特有的类型 和 python的数据类型间进行转换
pickle模块提供了四个功能:dumps、dump(序列化,存)、loads(反序列化,读)、load (不仅可以序列化字典,列表...可以把python中任意的数据类型序列化)
pickle
import pickle
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = pickle.dumps(dic)
print(str_dic) #一串二进制内容dic2 = pickle.loads(str_dic)
print(dic2) #字典import time
struct_time = time.localtime(1000000000)
print(struct_time)
f = open('pickle_file','wb')
pickle.dump(struct_time,f)
f.close()f = open('pickle_file','rb')
struct_time2 = pickle.load(f)
print(struct_time.tm_year)
shelve
shelve也是python提供给我们的序列化工具,比pickle用起来更简单一些。
shelve只提供给我们一个open方法,是用key来访问的,使用起来和字典类似。
shelve
import shelve
f = shelve.open('shelve_file')
f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'} #直接对文件句柄操作,就可以存入数据
f.close()import shelve
f1 = shelve.open('shelve_file')
existing = f1['key'] #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
f1.close()
print(existing)
这个模块有个限制,它不支持多个应用同一时间往同一个DB进行写操作。所以当我们知道我们的应用如果只进行读操作,我们可以让shelve通过只读方式打开DB
shelve只读
import shelve
f = shelve.open('shelve_file', flag='r')
existing = f['key']
f.close()
print(existing)
由于shelve在默认情况下是不会记录待持久化对象的任何修改的,所以我们在shelve.open()时候需要修改默认参数,否则对象的修改不会保存。
设置writeback
import shelve
f1 = shelve.open('shelve_file')
print(f1['key'])
f1['key']['new_value'] = 'this was not here before'
f1.close()f2 = shelve.open('shelve_file', writeback=True)
print(f2['key'])
f2['key']['new_value'] = 'this was not here before'
f2.close()
writeback方式有优点也有缺点。优点是减少了我们出错的概率,并且让对象的持久化对用户更加的透明了;但这种方式并不是所有的情况下都需要,首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗,并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间。因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入。
sys模块
sys模块是与python解释器交互的一个接口
ys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys.maxint 最大的Int值 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform 返回操作系统平台名称