python学习之路-day4-装饰器&json&pickle
本节内容
- 迭代器&生成器
- 装饰器
- Json & pickle 数据序列化
一、生成器
1、列表生成式
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
2、生成器
只有在调用时才会生成相应的数据,只有一个方法:__next__()方法。next(),也就是又next方法的
生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]
改成()
,就创建了一个generator:
>>> L = [x * x for x in range()] >>> L [, , , , , , , , , ] >>> g = (x * x for x in range()) >>> g <generator object <genexpr> at 0x1022ef630>
创建L
和g
的区别仅在于最外层的[]
和()
,L
是一个list,而g
是一个generator。
我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?
如果要一个一个打印出来,可以通过next()
函数获得generator的下一个返回值:
>>> next(g) >>> next(g) >>> next(g) >>> next(g) >>> next(g) >>> next(g) >>> next(g) >>> next(g) >>> next(g) >>> next(g) >>> next(g) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
如果一个函数定义中包含yield
关键字,那么这个函数就不再是一个普通函数,而是一个generator:
普通函数:
1 def fib(max):
2 n,a,b = 0,0,1
3 while n<max:
4 print(b)
5 #yield b
6 a,b=b,a+b
7 n = n+1
8 return 'done'
9 t = fib(11)
10 print(t)
11 输出结果:
12 1
13 1
14 2
15 3
16 5
17 8
18 13
19 21
20 34
21 55
22 89
23 done 上面函数变成生成器,只需要把print(b)改为yield b就可以了: def fib(max): n,a,b = 0,0,1 while n<max: #print(b) yield b a,b=b,a+b n = n+1 return 'done' t = fib(11) print(t) 输出结果: <generator object fib at 0x00000000010F59E8>
例
注:赋值语句:a, b
=
b, a
+
b
相当于:
t = (b, a + b) # t是一个tuple
a = t[0]
b = t[1]
这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return
语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()
的时候执行,遇到yield
语句返回,再次执行时从上次返回的yield
语句处继续执行。
变成生成器之后并没有运行,而是在要输出的时候才运行:(每次next,输出一次)
def fib(max):
n,a,b = 0,0,1
while n<max:
#print(b)
yield b #碰到yield,程序中断, 出到函数外面在遇到next的时候在回来接着往下走 a,b=b,a+b
n = n+1
return 'done'
t = fib(11)
print(t)
print(t.__next__())
print(t.__next__())
print(t.__next__())
print("---------")
print(t.__next__())
输出结果:
1
1
2
---------
3
再来一例:
def consumer(name):
print("%s 准备吃包子啦!" %name)
while True:
baozi = yield #碰到yield退出程序,遇到c.__next__()时在进来继续往下走
print("包子[%s]来了,被【%s】吃了!" %(baozi,name))
c = consumer("lsp")
c.__next__()
c.__next__()
c.__next__()
c.__next__() 输出结果:
lsp 准备吃包子啦!
包子[None]来了,被【lsp】吃了!
#yield是none值,可以通过send给yield传值,见下例
包子[None]来了,被【lsp】吃了!
包子[None]来了,被【lsp】吃了!
**最后一例**
import time
def consumer(name):
print("%s 准备吃包子啦!" %name)
while True:
baozi = yield #碰到yield退出程序,遇到c.__next__()或者(send)时在进来继续往下走(只要有yield就是生成器)
print("包子[%s]来了,被【%s】吃了!" %(baozi,name))
def producer(name):
c=consumer('lw') #因为是生成器,所以不会输出任何东西
c2 = consumer('lsp')
c.__next__() #输出lw准备吃包子了
c2.__next__() #输出lsp准备吃包子了
print("我开始准备做包子了!") #输出我开始做包子了
for i in range(3): #循环
time.sleep(1) #sleep 1秒
print("做了1个包子") #做了一个包子
c.send(i) #将i的值传给yield
c2.send(i) #将i的值传给yield
producer("alex") #调用函数
输出结果:
lw 准备吃包子啦!
lsp 准备吃包子啦!
我开始准备做包子了!
做了1个包子
包子[0]来了,被【lw】吃了!
包子[0]来了,被【lsp】吃了!
做了1个包子
包子[1]来了,被【lw】吃了!
包子[1]来了,被【lsp】吃了!
做了1个包子
包子[2]来了,被【lw】吃了!
包子[2]来了,被【lsp】吃了!
二、迭代器
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable
只要有next的方法,就一定是一个迭代器
for line in f: #就是一个迭代器
接上面生成器的例子:
def fib(max):
n,a,b = 0,0,1
while n<max:
#print(b)
yield b
a,b=b,a+b
n = n+1
return 'done'
t = fib(11)
for i in t:
print(i)
输出结果:
1
1
2
3
5
8
13
21
34
55
89
三、装饰器
装饰器:本质是函数(装饰其他函数),就是为其他函数添加附加功能
原则:
- 不能修改被修饰的函数的源代码
- 不能修改被装饰的函数的调用方式
原函数代码和调用方式 不变,不知道有装饰器在装饰他(一句话,源函数代码和调用方式一点都不变,实现改变功能的函数,即是装饰器)
例一:
import time
def bar(): #原函数
time.sleep(3)
print('in the bar')
def test1(func):
start_time=time.time()
func() #调用函数bar,因为func= bar,所以这里func()== bar(),即调用上面的函数
stop_time=time.time()
print("the func time is %s" %(stop_time-start_time)) #bar() #原函数调用方式
test1(bar) #调用函数test1,func = bar ,这样虽然实现了修改原函数功能,但是调用方式改变了
例二:
原函数:
import time
def test1(): # 原函数1
print("this is test1")
def test2(): #原函数2
print("this is test2")
test1() #原函数调用方式
test2() #原函数调用方式
-----------------------------
加装饰器(加功能:程序运行时间) import time
def timer(func):
def deco():
start_time = time.time()
func() #test1 = func()--->test1() //#test2 = func()--->test2()
stop_time = time.time()
print("the func run time is %s" %(stop_time-start_time))
return deco #将deco的函数的内存地址返回,就是test1 == deco函数的内存地址!
@timer #test1=timer(test1) test1 == deco函数的内存地址!
def test1(): #test1 == deco函数的内存地址!test1()即执行deco函数,真正的test1()到deco函数里面遇到func()才会执行
time.sleep(1)
print("this is test1")
@timer #test2=timer(test1)
def test2():
time.sleep(1)
print("this is test2")
test1()
test2()
终极装饰器:
# __author__ = 'lw'
import time
user,passwd = 'lw','lw123'
def auth(auth_type):
print('auth_func:',auth_type)
def outer_wrapper(func):
def wrapper(*args,**kwargs):
print("wrapper func args:",*args,**kwargs)
if auth_type == "local":
username = input("Username:").strip()
password = input("password:").strip()
if username == user and passwd == password:
print("\033[32;1mUser has passwd authentication\033[0m")
res = func(*args,**kwargs) #from home
print("---after authentication")
return res
else:
exit("\033[31;1mInvalid username or password\033[0m")
elif auth_type == "ldap":
print("welcome to ldap")
return wrapper
return outer_wrapper
def index():
print("welcome to index page")
@auth(auth_type="local") #home = wrapper()
def home():
print("welcome to home page")
return "from home"
def bbs():
print("welcome to bbs page")
index()
print(home()) #wrapper()
bbs()
四、 json&&pickle
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。
json在所以语言中通用
引用模块
import json
重要函数
- 编码:把一个Python对象编码转换成Json字符串 json.dumps()
- 解码:把Json格式字符串解码转换成Python对象 json.loads()
例子
序列化
将内存中的信息写入到文件
#!/usr/bin/python import json
info = { 'name':'alex',
'age':'22'
}
f = open("test.txt","w") f.write(json.dumps(info)) f.close()
[root@test1 python]#
反序列化
将文件中的信息读取出来
[root@test1 python]# cat fanxuliehua.py
#!/usr/bin/python import json
f = open("test.txt","r") data = json.loads(f.read()) print(data)
print(data["name"]) [root@test1 python]# python fanxuliehua.py
{u'age': u'22', u'name': u'alex'}
alex
[root@test1 python]#
json只能序列化简单的数据类型,不能反序列化函数等复杂的数据类型,想要序列化复杂的数据,需要使用pickle,用法和json完全一样,只是序列化的时候变成二进制类型,即在打开文件的时候要用wb和rb
pickle.dump(info,f) ==f.write(pickle.dumps(info))
python学习之路-day4-装饰器&json&pickle的更多相关文章
- Python学习之路7☞装饰器
一:命名空间与作用域 1.1命名空间 局部命名空间: def foo(): x=1 def func(): pass 全局命名空间: import time class ClassName:pass ...
- Python学习之路6 - 装饰器
装饰器 定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能.原则:1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式 实现装饰器的知识储备: 1.函数即“变量” 2.高阶函 ...
- 迭代器/生成器/装饰器 /Json & pickle 数据序列化
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...
- 小白的Python之路 day4 装饰器前奏
装饰器前奏: 一.定义: 1.装饰器本质是函数,语法都是用def去定义的 (函数的目的:他需要完成特定的功能) 2.装饰器的功能:就是装饰其他函数(就是为其他函数添加附加功能) 二.原则: 1. 不能 ...
- 小白的Python之路 day4 装饰器高潮
首先装饰器实现的条件: 高阶函数+嵌套函数 =>装饰器 1.首先,我们先定义一个高级函数,去装饰test1函数,得不到我们想要的操作方式 import time #定义高阶函数 def deco ...
- Python-Day4 Python基础进阶之生成器/迭代器/装饰器/Json & pickle 数据序列化
一.生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面 ...
- Python成长之路_装饰器
一.初入装饰器 1.首先呢我们有这么一段代码,这段代码假设是N个业务部门的函数 def f1(aaa): print('我是F1业务') if aaa == 'f1': return 'ok' def ...
- python学习日记(函数--装饰器)
楔子 前提,我有一段代码(一个函数). import time def run_time(): time.sleep(0.1) print('我曾踏足山巅') 需求1:现在,我想计算这段代码的运行时间 ...
- 【Python学习之二】装饰器
装饰器 首先,给出装饰器的框架: def log(func): def wrapper(*args, **kw): print('call %s():' % func.__name__) return ...
随机推荐
- 使用C#对SQLLite进行操作
1.数据库连接(常用连接方法,示例) 1). 添加引用: System.Data.SQLite.DLL .2). 打开或创建数据库文件: SQLiteConnection.CreateFile(fil ...
- java反射学习笔记
1.java反射概念 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功 ...
- libpcap和WinPcap
能从物理上访问网络上的流量后,你需要用软件把它记录下来.这里,我们探究记录.解析和分析被捕获的数据包中最常用的软件库:libpcap和WinPcap.也将介绍包括tcpdump.Wireshark等基 ...
- 闲谈Tomcat性能优化
Tomcat在各位JavaWeb从业者常常就是默认的开发环境,但是Tomcat的默认配置作为生产环境,尤其是内存和线程的配置,默认都很低,容易成为性能瓶颈. 幸好Tomcat还有很多的提升空间.下文介 ...
- WCF数据通讯
Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NET Fra ...
- VG vs SS WE vs IM [20160815]
上单:慎,纳尔,艾克,艾瑞莉娅,普朗克 中单:弗拉基米尔,玛尔扎哈,卡尔玛,丽桑卓,索尔,崔斯特,辛德拉 打野:雷克赛,奈德丽,古拉加斯,伊莉丝,赫卡里姆,玛尔扎哈 下路:艾希,克格莫,烬,希维尔,布 ...
- 根据 MySQL 状态优化 ---- 1. 慢查询
查看 MySQL 服务器运行的各种状态值: mysql> show global status: 1. 慢查询 mysql> show variables like '%slow%'; + ...
- win7安装xampp,提示windows找不到-n文件(安装成功后,443端口占用,apache服务器无法正常启动)
1. 环境:win7 64位安装xampp 32位. xampp下载地址:https://www.apachefriends.org/download.html 2. 安装过程最后,报错,提示wind ...
- 【IIS8】在IIS8添加WCF服务支持
最近在做Silverlight,Windows Phone应用移植到Windows 8平台,在IIS8中测试一些传统WCF服务应用,发现IIS8不支持WCF服务svc请求,后来发现IIS8缺少对WCF ...
- 27. Best Time to Buy and Sell Stock && Best Time to Buy and Sell Stock II && Best Time to Buy and Sell Stock III
Best Time to Buy and Sell Stock (onlineJudge: https://oj.leetcode.com/problems/best-time-to-buy-and- ...