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 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用 ...
随机推荐
- _variant_t与其他数据类型的转换
转自:http://kuaixingdong.blog.hexun.com/29627840_d.html 我们先看看COM所支持的一些类型的基本类: (微软提供,在comdef.h中定义) 在COM ...
- [Android]高低API版本兼容之@TargetApi
使用@TargetApi annotaion, 使高版本API的代码在低版本SDK不报错 例如: AsyncTask.THREAD_POOL_EXECUTOR, 这个静态变量是API11才有的, 设置 ...
- STL中的Vector相关用法
STL中的Vector相关用法 标准库vector类型使用需要的头文件:#include <vector>. vector 是一个类模板,不是一种数据类型,vector<int> ...
- js 面向对象 继承机制
根据w3cschool上的描述:共有3种继承方法(对象冒充,原型链,混合) 1.对象冒充:构造函数ClassA使用this关键字给所有属性和方法赋值,使ClassA构造函数成为ClassB的方法,调用 ...
- Python学习-35.Python中的List Comprehensions(列表解释|列表生成式)
在某些情况下,我们需要对列表进行某些操作,例如对列表中的每一个元素都乘以2,这样一般来说就是遍历每个元素在乘以2.那么写下来就得两行了.而且这会修改原来的列表,如果要求不能修改原来的列表,又得多一行了 ...
- 实现EventHandler的监测
的监测", "category":"", "tags":"", "publish":&qu ...
- asp.net 网站监控方案
前言:监控web网站方法有很多种,这篇文章说一下对windows服务器 asp.net网站的监控 采用的方案,Powershell + Influxdb + Grafana 1.PowerShell ...
- Spring Boot - Spring Data
使用JPA 虽然JPA是一个标准,但spring中一般就是使用hibernate实现的 使用JPA(Java Persistence API,Java持久化API,是个规范,其实是借助Hibernat ...
- dpdk EAL: Error reading from file descriptor 23: Input/output error
执行test程序时输出: EAL: Error reading from file descriptor 23: Input/output error 原因: 在虚拟机添加的网卡,dpdk不支持导致的 ...
- JQuery Mobile - 为什么绑定事件后会被多次执行?
JQuery Mobile 在绑定事件时候,发现会被多次执行,为什么啊? 原来,jquery click 不是替换原有的function ,而是接着添加,所以才会执行次数越来越多,怎么办才能按需实现 ...