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 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用 ...
随机推荐
- 建立多人协作git仓库/git 仓库权限控制(SSH)
转载文章请保留出处 http://blog.csdn.net/defeattroy/article/details/13775499 git仓库是多人协作使用的,可以基于很多种协议,例如http.g ...
- jenkins构建随笔
/t:Rebuild/p:Configuration=Debug/p:VisualStudioVersion=12.0/p:WebProjectOutputDir=E:\wwwroot\3.WCFSv ...
- Excel 帮助无法正常工作的解决方法
Excel 中出现错误:帮助无法正常工作,但您仍可以转到 Office.com,以获得最新和最好的文章.视频和培训课程. 英文消息:Help isn't working, but you can st ...
- Microsoft.Office.Interop.Excel 导出Excel
; ; /// <summary> /// 使用 Excel.dll 导出 Excel /// </summary> /// <param name="list ...
- PHP RBAC权限管理 基于角色的访问控制演示
RBAC rbac:Role Based Access Controll,基于角色的访问控制. 今天理一理RBAC,话不多说,直接切入主题 功能需求: 权限管理(无限极) 角色管理(可以分配权限) 管 ...
- EF简易教程,从建表到表间关系
唐大兵博客 唐大兵的博客里记录了EF Code First从建表到表之间关系的详细内容. 汪杰的博客(EF里一对一.一对多.多对多关系的配置和级联删除) 汪杰的博客更简洁,但不够充实,读懂了唐大兵博客 ...
- Could not load file or assembly '$SharePoint.Project.AssemblyFullName$'
The fix is simple, do the following: 1. Open your project file in NotePad 2. Find the PropertyGrou ...
- pageadmin CMS网站建设教程:如何修改用户密码?
pageadmin CMS网站建设教程: 当我们想修改密码,该如何修改呢? 1. 首先,登录会员中心,会员中心的地址是在网址后面加上/member/login: 2. 例:我的网站地址是localho ...
- S11 day 95 RestFramework 之 视图
1. 基于APIVIEW视图序列化 我们会发现两个类有好多重复的代码.所以我们引入了GenericAPIView (继承了APIView) 2.Generic ApiVIew和 ListModel ...
- python+pcap+dpkt 抓包小实例
#!/usr/bin/env python # -*- coding: utf-8 -*- """ 网络数据包捕获与分析程序 """ imp ...