python笔记09-----装饰器,生成器,迭代器
1.装饰器
定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能
原则:1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
实现装饰器的知识储备:
1. 函数即“变量”
2. 高阶函数
a. 把一个函数名当做实参传给另一个函数(在不修改被装饰函数源代码的情况下为期添加功能)
b. 返回值中包含函数名(不修改函数的调用方式)
3. 嵌套函数
4. 高阶函数+嵌套函数=装饰器
1.1 实现简单的装饰器
def outer(fun):
def warper():
print("outer 1")
fun() #相当于把下边两个函数当参数传入进来
print("outer 3")
return warper @outer
def test1():
print("test1 2")
@outer
def test2():
print("test2 2")
test1()
test2()
-----------------结果-----------------
outer 1
test1 2
outer 3
outer 1
test2 2
outer 3
1.2 装饰器传参
简单难度的传参
def outer(fun):
def warper(*args,**kwargs):
print("加的第一个功能在函数之前")
fun(*args,**kwargs)
print("加的第二个功能在函数之后")
return warper @outer
def test1(*args,**kwargs):
print(args,kwargs)
return test1(123,"waa","yyy",name="wsy",Age=18)
----------------结果----------------------
加的第一个功能在函数之前
(123, 'waa', 'yyy') {'name': 'wsy', 'Age': 18}
加的第二个功能在函数之后
中等难度的传参
加入time模块记录执行时间
import time
def timer(func):
def deco(*args,**kwargs):
start = time.time()
print("装饰器:功能1")
func(*args,**kwargs)
print("装饰器:功能2")
end = time.time()
print("func run time is %s" %(end - start))
return deco
@timer
def test1():
time.sleep(1)
print("in the test1")
@timer
def test2(*args,**kwargs):
time.sleep(1)
print("in the test1",args,kwargs)
test1()
test2(1,2,3,4,name="wsy",age=20)
--------------------结果------------------------
装饰器:功能1
in the test1
装饰器:功能2
func run time is 1.0000572204589844
装饰器:功能1
in the test1 (1, 2, 3, 4) {'name': 'wsy', 'age': 20}
装饰器:功能2
func run time is 1.0000572204589844
多重认证 第一个页面认证成功直接进入其他两个页面
user,passwd = "wsy",""
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": # 如果装饰器参数是local 就
username = input("Username:").strip() # 输入用户名
password = input("Password:").strip() # 输入密码
if user == username and passwd == password: # 判断如果正确
print("\033[32;1mUser has passwd authentication\033[0m")
res = func(*args,**kwargs) #from home
print("-------after authenticaion")
return res
else:
exit("\033[31;1mInvalid username or password \033[0m")
elif auth_type == "ldap": # 如果装饰器参数是ldap
print("hehe")
return wrapper
return outer_wrapper def index():
print("welcome to index page") @auth(auth_type="local") def home():
print("welcome to home page")
return "from home"
@auth(auth_type="ldap")
def bbs():
print("welcome to bbs page")
index()
print (home())
bbs()
-----------------------结果-----------------------
auth func: local
auth func: ldap
welcome to index page
wrapper func args:
Username:wsy
Password:123
User has passwd authentication
welcome to home page
-------after authenticaion
from home
wrapper func args:
hehe
2.生成器
生成器
通过列表生成式,我们可以直接创建一个列表。但是受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量空间,在py中,这种一遍循环一遍计算的机制,称为生成器
终端命令行执行 >>> a = [1,2,3] >>> [i*2 for i in range(10)] -----------------输出结果----------------- [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
列表生成器
终端执行:
>>> ( i*2 for i in range(10))
-------------------输出结果------------------------ <generator object <genexpr> at 0x00000000021859E8> >>>b = ( i*2 for i in range(10)) >>> for i in b: ... print(i)
-------------------输出结果------------------------- 0 2 4 6 8 10 12 14 16 18
range
生成器 只有在调用时才会生成相应的数据
只记住当前位置
只有一个__next__()方法
a = (i*2 for i in range(100))
print(a.__next__())
print(a.__next__())
print(a.__next__())
print(a.__next__())
---------------输出结果-------------------
0
2
4
6
我们创建了一个generator(生成器)后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误
generator(生成器)非常强大,如果推算的算法比较复杂,用列斯列表生成式的for循环无法实现的时候,还可以用函数来实现
2.1 斐波那契数列
菲波纳契数列,除第一个和第二个数外,任意一个数都可由前两个数相加得到
def fib(max):
n, a, b = 0, 0, 1
while (n < max):
print(b)
a, b = b, a+b
n += 1 fib(10)
---------------------------------------
1
1
2
3
5
8
13
21
34
55
2.2 yield
def fib(max):
n,a,b = ,,
while (n < max):
yield b
a,b = b, a+b
n +=
f = fib()
for i in range():
print(f.__next__())
--------------输出结果-----------------
2.3 yield 实现单线程并行
import time
def consumer(name):
while True:
baozi = yield
print("包子[%s]来了,被[%s]吃了" %(baozi,name)) c = consumer("wsy")
c.__next__() def producer(name):
c = consumer('猫')
c2 = consumer('狗')
c.__next__()
c2.__next__()
print("开始吃")
for i in range(10):
time.sleep(1)
print("做了1个包子,分两半")
c.send(i)
c2.send(i)
producer("wsy")
---------------------------结果------------------------
开始吃
做了1个包子,分两半
包子[0]来了,被[猫]吃了
包子[0]来了,被[狗]吃了
做了1个包子,分两半
包子[1]来了,被[猫]吃了
包子[1]来了,被[狗]吃了
做了1个包子,分两半
包子[2]来了,被[猫]吃了
包子[2]来了,被[狗]吃了
做了1个包子,分两半
包子[3]来了,被[猫]吃了
包子[3]来了,被[狗]吃了
做了1个包子,分两半
包子[4]来了,被[猫]吃了
包子[4]来了,被[狗]吃了
做了1个包子,分两半
包子[5]来了,被[猫]吃了
包子[5]来了,被[狗]吃了
做了1个包子,分两半
包子[6]来了,被[猫]吃了
包子[6]来了,被[狗]吃了
做了1个包子,分两半
包子[7]来了,被[猫]吃了
包子[7]来了,被[狗]吃了
做了1个包子,分两半
包子[8]来了,被[猫]吃了
包子[8]来了,被[狗]吃了
做了1个包子,分两半
包子[9]来了,被[猫]吃了
包子[9]来了,被[狗]吃了
吃包子例子
3.迭代器
我们已经知道,可以直接作用于for循环的数据类型有一下几种:
1.集合数据类型,如list,tuple,dict,set,str等
2.生成器,包括生成器和带yield的generator function
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable
可以使用isinstance()判断一个对象是否是Iterable对象:
命令行
>>> from collections import Iterable
>>> isinstance([],Iterable)
True
>>> isinstance({},Iterable)
True
>>> isinstance('abc',Iterable)
True
>>> isinstance((x for x in range(10)),Iterable)
True
>>> isinstance(100,Iterable)
False
判断是否为iterable对象
而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,知道最后抛出StopIteration错误表示无法继续返回下一个值了。
*可以被next()函数调用并不断返回下一个值得对象成为迭代器:Iterator
可以使用isinstance()判断一个对象是否是Iterator对象:
#结论:生成器一定是迭代器 迭代器不一定是生成器
生成器都是Iterator(迭代器)对象,但list,dict,str虽然是iterable(可迭代)却不是Iterator(迭代器)
把list,dict,str等Iterable变成Iterator可以使用iter()函数:
>>> a
[1, 2, 3]
>>> iter(a)
<list_iterator object at 0x0000000002150898>
>>> b = iter(a)
>>> b.__next__()
1
>>> b.__next__()
2
>>> b.__next__()
只要有next()函数 一定是迭代器
python笔记09-----装饰器,生成器,迭代器的更多相关文章
- 跟着ALEX 学python day4集合 装饰器 生成器 迭代器 json序列化
文档内容学习于 http://www.cnblogs.com/xiaozhiqi/ 装饰器 : 定义: 装饰器 本质是函数,功能是装饰其他函数,就是为其他函数添加附加功能. 原则: 1.不能修改被装 ...
- python三大器(装饰器/生成器/迭代器)
1装饰器 1.1基本结构 def 外层函数(参数): def 内层函数(*args,**kwargs); return 参数(*args,**kwargs) return 内层函数 @外层函数 def ...
- Python自动化 【第四篇】:Python基础-装饰器 生成器 迭代器 Json & pickle
目录: 装饰器 生成器 迭代器 Json & pickle 数据序列化 软件目录结构规范 1. Python装饰器 装饰器:本质是函数,(功能是装饰其它函数)就是为其他函数添加附加功能 原则: ...
- python笔记 - day4-之装饰器
python笔记 - day4-之装饰器 需求: 给f1~f100增加个log: def outer(): #定义增加的log print("log") ...
- python 函数之装饰器,迭代器,生成器
装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...
- python函数、装饰器、迭代器、生成器
目录: 函数补充进阶 函数对象 函数的嵌套 名称空间与作用域 闭包函数 函数之装饰器 函数之迭代器 函数之生成器 内置函数 一.函数补充进阶 1.函数对象: 函数是第一类对象,即函数可以当作数据传递 ...
- python 有参装饰器与迭代器
1.有参装饰器 模板: def auth(x): def deco(func): def timmer(*args,**kwargs ): res = func(*args,**kwargs ) re ...
- Python笔记:装饰器
装饰器 1.特点:装饰器的作用就是为已存在的对象添加额外的功能,特点在于不用改变原先的代码即可扩展功能: 2.使用:装饰器其实也是一个函数,加上@符号后放在另一个函数“头上”就实现了装饰 ...
- 20.python笔记之装饰器
装饰器 装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作. 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插 ...
- Python装饰器、迭代器&生成器、re正则表达式、字符串格式化
Python装饰器.迭代器&生成器.re正则表达式.字符串格式化 本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用 ...
随机推荐
- ios开发 ad hoc怎么用
简单的说就是这样 ad hoc 方式是苹果用来给未上线的app做测试用的,首先你要在苹果开发平台上申请一个ad hoc的证书,再在profile中生成一个ad hoc 的profile文件(只需要在生 ...
- Eclipse ADT 与VS 常用的快捷键 对比学习
注:以下说的类型于VS,是指:VS+Resharper的快捷键,我是采用了Resharper作为VS的快捷键. 导航 Ctrl+1 快速修复 (类似于VS的alt+enter) Ctrl+D: 删除当 ...
- LeetCode133:Clone Graph
题目: Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. ...
- dorado7-HelloWorld
1.首先在Tomat中将 Auto reloding enable去掉,去掉的目的不用每次更改代码,都要重新部署 2.创建dorado视图文件 2.1 视图文件的格式为xml 2.2 在view中添加 ...
- C#线程运用基础
ThreadStart ts=new ThreadStart(a.f);//ThreadStart 是一个委托,用以关联a.f方法Thread th=new Thread (ts);//Thread是 ...
- C# 获取每一个像素点的RGB
int x, y; x = e.X; y = e.Y; Color pixel = MyImage.GetPixel(x, y); byte R = pixel.R; byte G = pixel.G ...
- C#HttpUtility.UrlEncode 大写问题
工作上和另一个公司对接,调对方的api需要用到md5加密,加密前要使用HttpUtility.UrlEncode,对方接口一直返回验证错误,定位了问题发现是中文编码使用HttpUtility.UrlE ...
- 编译Bootstrap,定制自己的模板
完全不懂LESS,也懒的去学习它,凭多年的经验,感觉也不用专门花时间去学习了.反正它应该是很成熟的,能执行即可.我用的是WIN7,为了定制颜色等各种特性,需要重新编译Bootstrap.在网上到处中, ...
- C#使用MongoDb来存储文件
近期在写一个小玩意,需要保存一些图片,以前我采用的是FTP或者直接数据库保存文件,用FTP来保存文件感觉比较麻烦,用数据库吧,还要改字段类型,修改代码,修改查询语句,懒得改. 以前看过mongonDb ...
- 应用于电力电子变压器的双向DC_DC变换器综述(学习笔记)
PET(Powerelectronictransformer):电力电子变压器 PET所具有的优点: (1)体积小.重量轻.无变压器油的污染: (2)具备功率因数调节能力,减小电网谐波污染: (3)能 ...