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. SoC FPGA JTAG电路设计 要点

    JTAG协议制定了一种边界扫描的规范,边界扫描架构提供了有效的测试布局紧凑的PCB板上元件的能力.边界扫描可以在不使用物理测试探针的情况下测试引脚连接,并在器件正常工作的过程中捕获运行数据. SoC ...

  2. 如何充分利用 Windows Phone 高清屏幕

    Nokia 最近发布两款6寸大屏手机:Lumia 1520 和 Lumia 1320.为了支持这种设备 WP 升级了操作系统GDR3 支持了 1080P 的高清分辨率(1520),虽然GER3 是提供 ...

  3. IDEA13 项目配置

    之前用了一段时间的idea,有些老的代码,用eclipse跑了一下,比较麻烦,于是试用一下idea,最后,项目可以顺利跑起来. 对项目的配置,主要是在F4中,即:Module Setting,在模块的 ...

  4. Node.js-Usage & Example

    Usage# node [options] [v8 options] [script.js | -e "script"] [arguments] Please see the Co ...

  5. Android studio项目预览的时候提示错误ActionBarOverlayLayout

    android studio打开项目(别人的demo),提示页面没法预览.截图如下 根据查询,是主题没法正常显示,需要修改样式.样式文件的路径为res\values\styles.xml,截图如下. ...

  6. KeyChainWrapper - keychain简单使用

    1 keyChainWrapper是MRC代码,要禁用ARC -fno-objc-arc 2 要导入Security.framework框架 3 获得一个不变的UUID - (BOOL)applica ...

  7. jzoj5864

    本來這道題該100的,沒想到考試沒想最短路,直接跑暴力了 實際上這道題有原題跳樓機 那道題在模x的意義下統計答案 現在,我們要統計n個數的答案 30pts為提高組原題 剩下70pts,可以記dis[i ...

  8. Trie-648. Replace Words

    In English, we have a concept called root, which can be followed by some other words to form another ...

  9. Educational Codeforces Round 34 (Rated for Div. 2) C. Boxes Packing

    C. Boxes Packing time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  10. 前端html页面学习---html部分

    作为一个后台开发人员:本篇博客主要是关注前后台交互时需要掌握的html技术,不涉及css这一块的内容:主要是自学过程中的备忘 1:html常用标签标签的学习:不列出结束标签 <p>:段落: ...