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-----装饰器,生成器,迭代器的更多相关文章

  1. 跟着ALEX 学python day4集合 装饰器 生成器 迭代器 json序列化

    文档内容学习于 http://www.cnblogs.com/xiaozhiqi/  装饰器 : 定义: 装饰器 本质是函数,功能是装饰其他函数,就是为其他函数添加附加功能. 原则: 1.不能修改被装 ...

  2. python三大器(装饰器/生成器/迭代器)

    1装饰器 1.1基本结构 def 外层函数(参数): def 内层函数(*args,**kwargs); return 参数(*args,**kwargs) return 内层函数 @外层函数 def ...

  3. Python自动化 【第四篇】:Python基础-装饰器 生成器 迭代器 Json & pickle

    目录: 装饰器 生成器 迭代器 Json & pickle 数据序列化 软件目录结构规范 1. Python装饰器 装饰器:本质是函数,(功能是装饰其它函数)就是为其他函数添加附加功能 原则: ...

  4. python笔记 - day4-之装饰器

                 python笔记 - day4-之装饰器 需求: 给f1~f100增加个log: def outer(): #定义增加的log print("log") ...

  5. python 函数之装饰器,迭代器,生成器

    装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...

  6. python函数、装饰器、迭代器、生成器

    目录: 函数补充进阶 函数对象 函数的嵌套 名称空间与作用域 闭包函数 函数之装饰器 函数之迭代器 函数之生成器 内置函数 一.函数补充进阶 1.函数对象:  函数是第一类对象,即函数可以当作数据传递 ...

  7. python 有参装饰器与迭代器

    1.有参装饰器 模板: def auth(x): def deco(func): def timmer(*args,**kwargs ): res = func(*args,**kwargs ) re ...

  8. Python笔记:装饰器

    装饰器        1.特点:装饰器的作用就是为已存在的对象添加额外的功能,特点在于不用改变原先的代码即可扩展功能: 2.使用:装饰器其实也是一个函数,加上@符号后放在另一个函数“头上”就实现了装饰 ...

  9. 20.python笔记之装饰器

    装饰器 装饰器是函数,只不过该函数可以具有特殊的含义,装饰器用来装饰函数或类,使用装饰器可以在函数执行前和执行后添加相应操作. 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插 ...

  10. Python装饰器、迭代器&生成器、re正则表达式、字符串格式化

    Python装饰器.迭代器&生成器.re正则表达式.字符串格式化 本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用 ...

随机推荐

  1. api接口签名相关文章

    http://www.cnblogs.com/hnsongbiao/p/5478645.htmlhttp://www.cnblogs.com/codeon/p/5900914.html?from=ti ...

  2. 曲演杂坛--重建索引后,还使用混合分区么?(Are mixed pages removed by an index rebuild?)

    原文来自:http://www.sqlskills.com/blogs/paul/mixed-pages-removed-index-rebuild/ 在SQL SERVER 中,区是管理空间的基本单 ...

  3. UEditor编辑器两个版本任意文件上传漏洞分析

    0x01 前言 UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点 ,被广大WEB应用程序所使用:本次爆出的高危漏洞属于.NET版本,其它的 ...

  4. C# winform 窗体应用程序之图片上传Oracle数据库保存字段BLOB

    C# winform 窗体应用程序之图片上传Oracle数据库保存字段BLOB 我用的数据库是Oracle,就目前来看,许多数据库现在都倾向于Oracle数据库,对ORACLE数据库基本的操作也是必须 ...

  5. php不用递归完成无限分类,从表设计入手完整演示过程

    无限分类是什么就不废话了,可以用递归实现,但是递归从数据库取东西用递归效率偏低,如果从表设计入手,就很容易做到网站导航的实现,下面是某论坛导航,如下图 网上无限分类大多不全面,今天我会从设计表开始, ...

  6. 【Cocos2d-Js基础教学(1)JS -Mac配置篇】

    一.准备工作 Windows配置篇请见 http://cn.cocos2d-x.org/tutorial/show?id=1396 1.安装python 2.下载Android SDK Android ...

  7. Day14 作业

    1,整理今天的博客,写课上代码,整理流程图. 2,用列表推导式做下列小题 (1)   过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母 (2)   求(x,y)其中x是0-5之间的偶数,y是0- ...

  8. 898. Bitwise ORs of Subarrays

    We have an array A of non-negative integers. For every (contiguous) subarray B = [A[i], A[i+1], ..., ...

  9. 1.python的一些规范

    Python的一些规范 1.标识符 定义:允许作为名字的有效字符串集合 名字必须有实际意义,可读性好 首字母必须是字母或下划线(_) 剩下的字符可以是字母和数字或者下划线 大小写敏感 两种风格:con ...

  10. elasticsearch Geo Bounding Box Query

    Geo Bounding Box Query 一种查询,允许根据一个点位置过滤命中,使用一个边界框.假设以下索引文档: PUT /my_locations { "mappings" ...