什么是模块?

通俗来讲就像是具有特定功能的py文件,python中能开辟作用域的只有函数、类和模块, for循环不能开辟作用域,for循环内的变量为全局变量。if...else...同for循环一样。

分为以下几种类型:

  内置模块 : 安装python解释器的时候一起装上的
  第三方模块、扩展模块 :需要自己安装
  自定义模块 : 自己写的py文件

time模块

时间表示形式

在python中,通常有以下三种方式来表示时间:时间戳、结构化时间(struct_time)、格式化的时间字符串:

(1)时间戳(timestamp):时间戳是计算机能够识别的时间,表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。

import time
print(time.time())      #返回当前时间的时间戳,其中time.time(),第一个time为模块名,第二个time为方法
——————>1537864348.940804 

(2)结构化时间(struct_time):时间元组,结构化时间,是用来操作时间的。

import time
c=time.localtime()
print(c)
——————>time.struct_time(tm_year=2018, tm_mon=9, tm_mday=10, tm_hour=16, tm_min=30, tm_sec=42, tm_wday=2, tm_yday=116, tm_isdst=0) 

(3)格式化时间(Format String):时间字符串,是人能够看懂的时间。

print(time.strftime("%Y-%m-%d %X"))  #Y代表year,m为mouth,d为day,x为时间
——————>'2017-04-26 00:32:18'
print(time.strftime("%Y:%m))  #年月日时间分割可以更改,此处用“:”分割
——————>'2017:04'

几种时间形式之间的转化

时间戳时间——>结构化时间:localtime、gmtime

#gmtime为世界标准时间,一般不使用。
#localtime为东八区时间,为我们所在的时间,常使用localtime
timestamp = 15000000000
struct_time = time.localtime(timestamp)
struct_time = time.gmtime(timestamp)
print(struct_time)
——————>time.struct_time(tm_year=2445, tm_mon=5, tm_mday=1, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=0, tm_yday=121, tm_isdst=0)

结构化时间——>格式化时间:strftime

fmt_time = time.strftime('%Y-%m-%d %H:%M:%S',struct_time)
print(fmt_time)
————>2445-05-01 02:40:00struct_time = time.localtime(3000000000) # 默认当前时间
fmt_time = time.strftime('%Y-%m-%d %H:%M:%S',struct_time)
print(fmt_time)
————>2065-01-24 13:20:00

格式化时间——>结构化时间:strptime

str_time = '2018-8-8'  #也可叫做字符串时间转化为结构化时间
struct_time = time.strptime(str_time,'%Y-%m-%d')
print(struct_time)
————>time.struct_time(tm_year=2018, tm_mon=8, tm_mday=8, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=220, tm_isdst=-1)

结构化时间——>时间戳时间:mktime

timestamp = time.mktime(struct_time)  #当前结构化时间转化为时间戳
print(timestamp)
————>1533657600.0

 其他方法

sleep(secs)    # 线程推迟指定的时间运行,单位为秒。相当于IO操作。

计算两个格式化时间的时间差例题

import time
str1 = '2018-9-4 10:15:20'
str2 = '2018-9-3 22:48:20'
def time_diff(time_start,time_end,fmt = '%Y-%m-%d %H:%M:%S'):stamp_func = lambda t: time.mktime(time.strptime(t,fmt))stamp1 = stamp_func(time_end)stamp2 = stamp_func(time_start)t = abs(stamp1 - stamp2)ret = time.gmtime(t)return (ret.tm_year-1970,ret.tm_mon-1,ret.tm_mday-1,ret.tm_hour,ret.tm_min,ret.tm_sec)
ret = time_diff(str1,str2)
print(ret)

random模块

import random
print(random.random())      #输出大于0且小于1之间的小数
————>0.03231288445315539print(random.randint(1,5))   # 随机输出大于等于1且小于等于5之间的整数,[1,5]
————>4print(random.randrange(1,100,2))    # 随机任意数字之间随机奇数
————>2print(random.choice([1,'2',[3,4]]))      #随机取列表中的一个元素,结果为1或者2或者[3,4]
————>[3, 4]print(random.sample([1,'2',[3,4]],2))      #随机取列表中任意2个元素
————>[1, [3, 4]]print(random.uniform(1,3))      #随机取大于1小于3的小数
————>1.0122103690258861item=[1,2,3,4,5]
print(random.shuffle(item))     #直接输出,什么都没有
————>Nonerandom.shuffle(item)
print(item)
————>[1, 3, 5, 2, 4]
print(item)     #再次打印结果和上一次输出结果一样,需要重新打乱才能输出重新排序的列表
————>[1, 3, 5, 2, 4]
random.shuffle(item)
print(item)
————>[2, 3, 5, 1, 4]

发红包例题

import random as r
money = 200
num = 10
def lucky_money(money,num):ret = r.sample(range(1,money*100),num-1)ret.sort()ret.insert(0,0)ret.append(20000)for i in range(len(ret)-1):money = ret[i+1] - ret[i]yield money/100
for money in lucky_money(200,10):print(money)

生成六位数字字母验证码

def fun(n = 6,alph_flag = True):code = ''for i in range(n):c = str(random.randint(0,9))if alph_flag:alpha_upper = chr(random.randint(65,90))  #ASCII码65-90位置为26位大写字母alpha_lower = chr(random.randint(97,122))  #ASCII码97-122位置为26位小写字母c = random.choice([c,alpha_upper,alpha_lower])code += creturn code
ret = fun(6,False) # 可以传验证码指定长度,传Flase可以只打印纯数字验证码
print(ret)

hashlib模块

3.1 算法介绍

Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等。 什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。 摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。 摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。 而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。

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

import hashlib
md5_obj = hashlib.md5()  # md5只是hashlib摘要算法的一种,可以使用其他摘要算法。md5使用较多。
md5_obj.update('wuyiclara'.encode('utf-8'))   #使用.encode("utf8")或者加b强制转换成二进制方式都不会报错,在python2中不需要
ret = md5_obj.hexdigest()
print(ret)
————>68dccbba31766cf2d755115fbe6ba469  # 生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示

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

import hashlib
md5 = hashlib.md5()
md5.update(b'wuyi')
md5.update(b'clara')
print(md5.hexdigest())
————>68dccbba31766cf2d755115fbe6ba469
————>68dccbba31766cf2d755115fbe6ba469

MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。 另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似:

sha_obj = hashlib.sha1()
sha_obj.update('666'.encode('utf-8'))
ret = sha_obj.hexdigest()
print(ret)
————>cd3f0c85b158c08a2b113464991810cf2cdfc387

SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。 比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长。 

3.2 摘要算法应用

任何允许用户登录的网站都会存储用户登录的用户名和口令。如何存储用户名和口令呢?方法是存到数据库表中:

 
 
michael | 123456
bob     | abc999
alice   | alice2008

如果以明文保存用户口令,如果数据库泄露,所有用户的口令就落入黑客的手里。此外,网站运维人员是可以访问数据库的,也就是能获取到所有用户的口令。

正确的保存口令的方式是不存储用户的明文口令,而是存储用户口令的摘要,比如MD5:

michael  | e10adc3949ba59abbe56e057f20f883e
bob      | 878ef96e86145580c38c87f0410ad153
alice    | 99b1c2188db85afee403b1536010c2c9

考虑这么个情况,很多用户喜欢用123456,888888,password这些简单的口令,于是,黑客可以事先计算出这些常用口令的MD5值,得到一个反推表:

'e10adc3949ba59abbe56e057f20f883e''123456'
'21218cca77804d2ba1922c33e0151105''888888'
'5f4dcc3b5aa765d61d8327deb882cf99''password'

这样,无需破解,只需要对比数据库的MD5,黑客就获得了使用常用口令的用户账号。

对于用户来讲,当然不要使用过于简单的口令。但是,我们能否在程序设计上对简单口令加强保护呢?

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

def get_mad5(s):md5_obj = hashlib.md5('to give up'.encode('utf-8'))md5_obj.update(s.encode('utf-8'))ret = md5_obj.hexdigest()return ret
print(get_mad5('root'))
————>601be706bbcd09aa27a3c5799da15173

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

但是固定的盐 会导致恶意注册的用户密码泄露,有没有办法让使用相同口令的用户存储不同的MD5呢?

此时可以利用动态加盐的方法来提高账户安全性:

def get_md5(user,s):md5_obj = hashlib.md5(user.encode('utf-8'))md5_obj.update(s.encode('utf-8'))ret = md5_obj.hexdigest()return ret
print(get_md5('1521897246','85208520'))
————>9bb385ac8faa030f51fc8f8b05731f47print(get_md5('root','7410'))
————>548e9c730531e2ac1c723e56175ceaaaprint(get_md5('CDX','9630'))
————>183ab03244576bc91df336ce06d89fb2

这样,每个用户就都有一个固定的并且互不相同的“盐”。

摘要算法在很多地方都有广泛的应用。要注意摘要算法不是加密算法,不能用于加密(因为无法通过摘要反推明文),只能用于防篡改,

但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口令。

动态加盐登录例题

def login(s):
md5_obj = hashlib.md5()
md5_obj.update(s.encode('utf-8'))
ret = md5_obj.hexdigest()
return retwith open('userinfo') as f:username = input('username:')password = input('password:')for line in f:usr,pwd = line.strip().split('|')if username == usr and login(password) == pwd:print('登录成功')else:print('登录失败')

计算文件大小例题

import os
import hashlibdef get_file_path(file_path,buffer=1024):md5_obj = hashlib.md5()file_size = os.path.getsize(file_path)with open(file_path,'rb') as f:while file_size:content = f.read(buffer)file_size -= len(content)md5_obj.update(content)return md5_obj.hexdigest()
g = get_file_path('day26练习.py')
print(g)

os模块

os模块是一个和操作系统交互的模块,可以按照以下几类来划分:

1、文件和文件夹的操作

os.remove    删除一个文件
os.rename    ("oldname","newname") 重命名文件/目录
os.mkdir     生成单级目录;相当于shell中mkdir dirname
os.makedirs   ('dirn ame1/dirname2')可生成多层递归目录
os.rmdir      删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.removedirs  若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.listdir    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.stat       获取文件/目录信息

2、路径的操作

os.path.join   将多目录拼接后返回,第一个绝对路径之前的参数将被忽略
os.path.split   将路径分割成两个部分,目录、文件/文件夹的名字
os.path.dirname  返回这个path的上一级目录,其实就是os.path.split(path)的第一个元素
os.path.basename  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exits  判断这个路径是否存在,如果path存在,返回True;如果path不存在,返回False
os.path.isfile  判断是否存在的文件,如果path是一个存在的文件,返回True。否则返回False
os.path.isdir  判断是否文件夹目录,如果path是一个存在的目录,则返回True。否则返回False
os.path.abspath  规范文件目录、返回一个绝对路径
os.path.getsize  返回path的大小

3、和python程序的工作目录相关

os.getcwd()  获取当前的工作目录,即当前python脚本工作的目录路径  get current working dir
os.chdir  ("dirname")改变当前脚本工作目录;相当于shell下cd

4、执行操作系统命令

os.system  ("bash command")运行shell命令,直接显示
os.popen  ("bash command).read()运行shell命令,获取执行结果

5、双下__file__

__file__    文件中的一个内置变量,描述的是这个文件的绝对路径 

ps:stat 获取文件/目录信息 的结构说明:

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)是创建时间(详细信息参见平台的文档)。

stat结构说明

os模块的属性:os.linesep    输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'

os模块属性

re模块、正则表达式

什么是正则表达式?

官方定义:正则表达式(或 RE)是一种小型的、高度专业化的编程语言,是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。就其本质而言,和python语言没有什么直接关系,它只是被内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

在线测试工具:http://tool.chinaz.com/regex/

正则表达式的大致匹配过程是:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。如果表达式中有量词或边界,这个过程会稍微有一些不同,但也是很好理解的,下面是Python支持的正则表达式元字符和语法:

正则
待匹配字符
匹配结果
说明
[0123456789]
8
True
在一个字符组里枚举合法的所有字符,字符组里的任意一个字符和"待匹配字符"相同都视为可以匹配
[0123456789]
a
False
由于字符组中没有"a"字符,所以不能匹配
 

[0-9]
 

7
True
也可以用-表示范围,[0-9]就和[0123456789]是一个意思
 

[a-z]
 

s
 

True
 

同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示
 

[A-Z]
 

B
 

True
 

[A-Z]就表示所有的大写字母
 

[0-9a-fA-F]
 

e
 

True
 

可以匹配数字,大小写形式的a~f,用来验证十六进制字符

字 符

 

元字符
 

匹配内容
匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线
\s 匹配任意的空白符
\d 匹配数字
\n 匹配一个换行符
\t 匹配一个制表符
\b 匹配一个单词的结尾
^ 匹配字符串的开始
$ 匹配字符串的结尾
\W
匹配非字母或数字或下划线
\D
匹配非数字
\S
匹配非空白符
a|b
匹配字符a或字符b
()
匹配括号内的表达式,也表示一个组
[...]
匹配字符组中的字符
[^...]
匹配除了字符组中字符的所有字符

量 词

量词
用法说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

转义符   \

在正则表达式中,有很多有特殊意义的是元字符,比如\n和\s等,如果要在正则中匹配正常的"\n"而不是"换行符"就需要对"\"进行转义,变成'\\'。

在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\n",字符串中要写成'\\n',那么正则里就要写成"\\\\n",这样就太麻烦了。这个时候我们就用到了r'\n'这个概念,此时的正则是r'\\n'就可以了。

正则 待匹配字符 匹配
结果
说明
\n \n  False
因为在正则表达式中\是有特殊意义的字符,所以要匹配\n本身,用表达式\n无法匹配
\\n \n  True
转义\之后变成\\,即可匹配
"\\\\n" '\\n'  True
如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次
r'\\n' r'\n'  True
在字符串之前加r,让整个字符串不转义

贪婪匹配

贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配

正则 待匹配字符 匹配
结果
说明
<.*>

<script>...<script>

<script>...<script>
默认为贪婪匹配模式,会匹配尽量长的字符串
<.*?> r'\d'  

<script>
<script>

加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串
几个常用的非贪婪匹配Pattern
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

.*?的用法
. 是任意字符
* 是取 0 至 无限长度
? 是非贪婪模式。
何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在:
.*?x就是取前面任意长度的字符,直到一个x出现

re模块下的常用方法

import reret = re.findall('a', 'eva egon yuan')  # 返回所有满足匹配条件的结果,放在列表里
print(ret) #结果 : ['a', 'a']

ret = re.search('a', 'eva egon yuan').group()
print(ret) #结果 : 'a'
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

ret = re.match('a', 'abc').group()  # 同search,不过尽在字符串开始处进行匹配
print(ret)
#结果 : 'a'

ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret)  # ['', '', 'cd']

ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1)#将数字替换成'H',参数1表示只替换1个
print(ret) #evaHegon4yuan4

ret = re.subn('\d', 'H', 'eva3egon4yuan4')#将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)obj = re.compile('\d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())  #结果 : 123import re
ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
print(ret)  # <callable_iterator object at 0x10195f940>
print(next(ret).group())  #查看第一个结果
print(next(ret).group())  #查看第二个结果
print([i.group() for i in ret])  #查看剩余的左右结果

注意:

1.findall的优先级查询:

import reret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
print(ret)  # ['oldboy']     这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可

ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
print(ret)  # ['www.oldboy.com']

2.split的优先级查询

ret=re.split("\d+","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan']

ret=re.split("(\d+)","eva3egon4yuan")
print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan']#在匹配部分加上()之后所切出的结果是不同的,
#没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
#这个在某些需要保留匹配部分的使用过程是非常重要的。

正则表达式的应用实例

^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$ 校验登录名:只能输入5-20个以字母开头、
可带数字、“_”、“.”的字串
^[a-zA-Z]{1,30}$ 校验用户姓名:只能输入1-30个以字母开头的字串
^(\w){6,20}$ 校验密码:只能输入6-20个字母、数字、下划线
^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$ 校验普通电话、传真号码:可以“+”
或数字开头,可含有“-” 和 “ ”
^http[s]{0,1}:\/\/.+$/ 或 /^http[s]{0,1}:\/\/.{1,n}$ 校验URL
(表示url串的长度为length(“https://”) + n )
^[\u4E00-\u9FA5]+$ 校验纯中文字符
^[0-9]{1,20}$ 校验是否全由数字组成
^-?\d+$ 整数
^[0-9]*[1-9][0-9]*$ 正整数
^-[0-9]*[1-9][0-9]*$ 负整数
^\d+$ 非负整数(正整数 + 0)
^((-\d+)|(0+))$ 非正整数(负整数 + 0)
^\d+(\.\d+)?$ 非负浮点数(正浮点数 + 0)
^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 非正浮点数(负浮点数 + 0)
^(-?\d+)(\.\d+)?$ 浮点数
^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$ 正浮点数
^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$ 负浮点数
^[A-Za-z]+$ 由26个英文字母组成的字符串
^[A-Z]+$ 由26个英文字母的大写组成的字符串
^[a-z]+$ 由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$ 由数字和26个英文字母组成的字符串
^\w+$ 由数字、26个英文字母或者下划线组成的字符串
^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$ email地址
^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$ url
^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$ 年-月-日
^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$  月/日/年
(d+-)?(d{4}-?d{7}|d{3}-?d{8}|^d{7,8})(-d+)? 电话号码
^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$ IP地址
^([0-9A-F]{2})(-[0-9A-F]{2}){5}$ MAC地址
^[-+]?\d+(\.\d+)?$ 值类型正则表达式

序列化模块

什么是序列化?

我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

json

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

JSON表示的对象就是标准的JavaScript语言的对象一个子集,JSON和Python内置的数据类型对应如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import  json
i = 10
s = 'hello'
t = ( 1 , 4 , 6 )
l = [ 3 , 5 , 7 ]
d = { 'name' : "yuan" }
#序列化
json_str1 = json.dumps(i)     #将整型i转换为json字符串形式
json_str2 = json.dumps(s)     #将字符串'hello'转换为json字符串形式
json_str3 = json.dumps(t)     #将元组t=(1,4,6)转换为json字符串形式
json_str4 = json.dumps(l)     #将列表l=[3,5,7]转换为json字符串形式
json_str5 = json.dumps(d)     #将字典d={'name':"yuan"}转换为json字符串形式。当d有英文时,打印出的是unicode数据;当d内容为英语时,正常显示
print (json_str1)        #json能识别整型
- - - > 10                 #json的字符串10
print (json_str2)        #json不能识别字符串
- - - > "hello"               #打印双引号,jason识别不了单引号''
print (json_str3)        #json不能识别元组,识别不了(),默认转换为[]
- - - >[ 1 4 6 ]
print (json_str4)        #json能识别列表
- - - >[ 3 5 7 ]
print (json_str5)        #json能识别字典。jason识别不了单引号'',所以输出的都是双引号。
- - - >{ "name" "yuan" }

 

python在文本中的使用:  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#序列化
import  json
dic = { 'name' : 'alvin' , 'age' : 23 , 'sex' : 'male' }
print ( type (dic))
- - - >< class  'dict' >
data = json.dumps(dic)
print ( "type" , type (data))
- - - >< class  'str' >
print ( "data" ,data)
f = open ( '序列化对象' , 'w' )
f.write(data)           #等价于json.dump(dic,f)
f.close()
#反序列化
import  json
f = open ( '序列化对象' )
new_data = json.loads(f.read())     #等价于data=json.load(f)
print ( type (new_data))

json序列化 

把字典转换成json形式的字符串写入文件中 (两种方法效果一样,只是写法不同而已)

方法一:推荐用这种方法

1 #1、把字典转换成json形式的字符串写入文件中
2 import json
3 dic = {'name': 'clara'}
4 dic = json.dumps(dic)
5 f = open("hello", "w")
6 f.write(dic)

方法二:

1 import json
2 dic = {'name': 'clara'}
3 f = open("hello", "w")
4 dic = json.dump(dic, f)

执行结果:

会生成一个hello的文件,并写入内容:

1 {"name": "clara"}

json反序列化

先创建一个json_test文件,写入内容

1 {"name":"clara"} #只要符合json规范就可以把值取出来。  另一种示例:{'name':"clara"} #如果是'name' 的值是单引号就会报错。

再去取值

1 import json
2
3 with open("Json_test","r") as f:  #双引号可以直接把值取出来
4     data=f.read()
5     data=json.loads(data)
6     print(data["name"])

执行结果:

1 clara

注:无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads

pickle

可以转换为任意数据类型,比json转换数据类型丰富很多。pickle序列化后的结果为字节格式,json序列化后的结果为字符串格式。

pickle,完全为python设定的。不同语言之间用json。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#序列化
import  pickle
dic = { 'name' : 'clara' , 'age' : 19 , 'sex' : 'female' }
print ( type (dic))
- - - >< class  'dict' >
  
j = pickle.dumps(dic)     #pickle.dumps()序列化为字节。
print ( type (j))
- - - >< class  'bytes' >
  
  
f = open ( '序列化对象_pickle' , 'wb' ) #注意是w是写入str,wb是写入bytes,j是'bytes'
f.write(j)       #等价于pickle.dump(dic,f)
  
f.close()
#反序列化
import  pickle
f = open ( '序列化对象_pickle' , 'rb' )
  
data = pickle.loads(f.read()) #  等价于data=pickle.load(f)
  
print (data[ 'age' ])

 

Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。

总结:

Json模块提供了四个功能:dumps、dump、loads、load

pickle模块提供了四个功能:dumps、dump(序列化,存)、loads(反序列化,读)、load  (不仅可以序列化字典,列表...可以把python中任意的数据类型序列化

  dump()函数接受一个文件句柄和一个数据对象作为参数,把数据对象以特定的格式保存 到给定的文件中。当我们使用load()函数从文件中取出已保存的对象时,pickle知道如何恢复这些对象到它们本来的格式。

  dumps()函数执行和dump() 函数相同的序列化。取代接受流对象并将序列化后的数据保存到磁盘文件,这个函数简单的返回序列化的数据。

  loads()函数执行和load() 函数一样的反序列化。取代接受一个流对象并去文件读取序列化后的数据,它接受包含序列化后的数据的str对象, 直接返回的对象。

json是一种所有的语言都可以识别的数据结构。
如果我们将一个字典或者序列化成了一个json存在文件里,那么java代码或者js代码也可以拿来用。
但是如果我们用pickle进行序列化,其他语言就不能读懂这是什么了~
所以,如果序列化的内容是列表或者字典,还是建议使用json模块
但如果出于某种原因不得不序列化其他的数据类型,而未来还会用python对这个数据进行反序列化的话,那么就可以使用pickle

转载于:https://www.cnblogs.com/Clara51/p/9622554.html

【编辑中】python 常用模块相关推荐

  1. Python中的常用模块

    1.sys模块(内置模块) 在sys模块中定义了一些函数和变量,用来设置和获取系统的信息. # Python中的常用模块:sys模块 import sys sys.path.append('./tes ...

  2. 实战篇一 python常用模块和库介绍

    # -_-@ coding: utf-8 -_-@ -- Python 常用模块和库介绍 第一部分:json模块介绍 import json 将一个Python数据结构转换为JSON: dict_ = ...

  3. python常用模块大全总结-常用python模块

    广告关闭 2017年12月,云+社区对外发布,从最开始的技术博客到现在拥有多个社区产品.未来,我们一起乘风破浪,创造无限可能. python常用模块什么是模块? 常见的场景:一个模块就是一个包含了py ...

  4. 对于python来说、一个模块就是一个文件-python常用模块

    python常用模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用pyt ...

  5. python常用模块之shelve模块

    python常用模块之shelve模块 shelve模块是一个简单的k,v将内存中的数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据类型 我们在上面讲json.pickle ...

  6. Python+常用模块(2).md

    Python 常用模块 1. random模块 1.1 导入模块 import random 1.2 random.random() 生成一个从0到1的随机浮点数 1.3 random.uniform ...

  7. python用什么来写模块-Python常用模块——模块介绍与导入

    Python常用模块--模块介绍与导入 一.什么是模块? 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分 ...

  8. Python 常用模块总结

    Python 常用模块总结 1.random 2.math 3.os 4.os.path 5.sys 6.hashlib 7.hmac 8.time 9.datetime 10.calendar 11 ...

  9. python常用模块-调用系统命令模块(subprocess)

    python常用模块-调用系统命令模块(subprocess) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. subproces基本上就是为了取代os.system和os.spaw ...

  10. python常用模块资料

    python常用模块资料 1.os模块 os模块包装了不同操作系统的通用接口,使用户在不同操作系统下,可以使用相同的函数接口,返回相同结构的结果. os.name:返回当前操作系统名称('posix' ...

最新文章

  1. Python matplotlib可视化:用Matplotlib的bar_label函数自定义条形图的数值标签、用Matplotlib的bar_label函数为条形图添加数值标记(在每一个条形的中部)
  2. php mysql cms 商城,国内最常用的PHP+MySql免费CMS系统大全
  3. 全面开启线上参会报名!CNCC线上与现场参会者共赴技术盛宴!
  4. js条件语句,用if...else if....else方程ax2+bx+c=0一元二次方程。求根
  5. SQL 分组使用案例
  6. iPhone 13 Pro手机壳曝光 网友:更丑了
  7. 超市收银机属于通用计算机,我是一名刚入超市做收银的,我录入货品后微信收钱之后没有在超市电脑上按确定导入账目导致超市系统上多出来钱这改正过来会很难吗?...
  8. LinuxMint下的Orionode源码安装
  9. 自学python能学成吗-Python能自学成功吗?
  10. git学习笔记(2-git初始化配置)
  11. 干货满满,30个Python源代码!
  12. 商丘学院计算机考研,商丘学院院校简介_商丘学院研究生院 - 中国考研网
  13. 10月11日科技联播:美股暴跌引全球股市崩盘;腾讯跌出全球市值前十
  14. ubuntu14 teamviewer使用
  15. 【t100】汤姆斯的天堂梦
  16. 致远项目管理SPM系统之项目立项审批
  17. Java 第十一届 蓝桥杯 省模拟赛 小明植树(DFS)
  18. 贤者之路,cuda版本convertto实现(与OPENCV 3.4 CPU版本数值一致)
  19. HQL和Criteria
  20. vue2.9.6版本下创建vue-cli脚手架

热门文章

  1. NodeJS原生后台开发教程
  2. 妙赞大讲糖:对糖尿病有益的六个方面
  3. linux实操篇,定时任务调度
  4. 破阵子青铜团队介绍以及项目背景介绍
  5. android识别不了手机号码,手机检测不到sim卡的问题解决方法【图文教程】
  6. Python实现人脸检测(个人、多人、视频)
  7. modified content, untracked content
  8. Zotero 超好用插件的下载链接及配置方法(PDF-translate/ZotFile/茉莉花/Zotero Scihub)
  9. CF467D Fedor and Essay 有向图强连通分量+缩点
  10. codeforces 467B - Fedor and New Game