一、装饰器

1.定义

  本质就是函数,功能 为其它函数添加附加功能

  原则:

  • 不修改被修饰函数的源代码
  • 不修改被修饰函数的调用方式

  装饰器的知识储备

  装饰器 = 高阶函数+函数嵌套+闭包

  这里面要明确高阶函数的定义

  1. import time#导入时间模块儿
  2. def foo(func): # func = test
  3. def bar(*args,**kwargs):
  4. start_time = time.time()
  5. res=func(*args,**kwargs) # 这里就是在运行test() 赋予变量
  6. stop_time = time.time()
  7. print("狼来了的时间为%s" %(stop_time-start_time))
  8. return res # 返回test()的值
  9. return bar
  10. @foo # @foo 相当于 test=foo(test) 调用foo函数并将test传给func
  11. def test(name,age):
  12. time.sleep()
  13. print("名字叫%s年龄为%s的狼来了" %(name,age))
  14. return "村里的羊被吃了"
  15. ret = test("灰太狼",age=) # test()意在运行bar() # 输出res的返回值
  16. print(ret)
  17.  
  18. 装饰器模型

装饰器模型

  装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

先定义一个基本的装饰器:

  1. ########## 基本装饰器 ##########
  2. def orter(func): #定义装饰器
  3. def inner():
  4. print("This is inner before.")
  5. s = func() #调用原传入参数函数执行
  6. print("This is inner after.")
  7. return s #return原函数返回值
  8. return inner #将inner函数return给name函数
  9.  
  10. @orter #调用装饰器(将函数name当参数传入orter装饰器)
  11. def name():
  12. print("This is name.")
  13. return True #name原函数return True
  14.  
  15. ret = name()
  16. print(ret)
  17.  
  18. 输出结果:
  19. This is inner before.
  20. This is name.
  21. This is inner after.
  22. True

1.给装饰器传参数:

  1. ############ 装饰器传参数 ###########
  2. def orter(func):
  3. def inner(a,b): #接收传入的2个参数
  4. print("This is inner before.")
  5. s = func(a,b) #接收传入的原函数2个参数
  6. print("This is inner after.")
  7. return s
  8. return inner
  9.  
  10. @orter
  11. def name(a,b): #接收传入的2个参数,并name整体函数当参数传入orter装饰器
  12. print("This is name.%s,%s"%(a,b))
  13. return True
  14.  
  15. ret = name('nick','jenny') #传入2个参数
  16. print(ret)
  17.  
  18. 输出结果:
  19. This is inner before.
  20. This is name.nick,jenny
  21. This is inner after.
  22. True

给装饰器传万能参数:

  1. ########## 万能参数装饰器 ##########
  2. def orter(func):
  3. def inner(*args,**kwargs): #万能参数接收多个参数
  4. print("This is inner before.")
  5. s = func(*args,**kwargs) #万能参数接收多个参数
  6. print("This is inner after.")
  7. return s
  8. return inner
  9.  
  10. @orter
  11. def name(a,b,c,k1='nick'): #接受传入的多个参数
  12. print("This is name.%s,%s"%(a,b))
  13. return True
  14.  
  15. ret = name('nick','jenny','car')
  16. print(ret)
  17.  
  18. 输出结果:
  19. This is inner before.
  20. This is name.nick,jenny
  21. This is inner after.
  22. True

2.一个函数应用多个装饰器方法:

  1. ########### 一个函数应用多个装饰器 #########
  2.  
  3. def orter(func):
  4. def inner(*args,**kwargs):
  5. print("This is inner one before.")
  6. print("This is inner one before angin.")
  7. s = func(*args,**kwargs)
  8. print("This is inner one after.")
  9. print("This is inner one after angin.")
  10. return s
  11. return inner
  1. def orter_2(func):
  2. def inner(*args,**kwargs):
  3. print("This is inner two before.")
  4. print("This is inner two before angin.")
  5. s = func(*args,**kwargs)
  6. print("This is inner two after.")
  7. print("This is inner two after angin.")
  8. return s
  9. return inner
  1. @orter #将以下函数整体当参数传入orter装饰器
  2. @orter_2 #将以下函数当参数传入orter_2装饰器
  3. def name(a,b,c,k1='nick'):
  4. print("This is name.%s and %s."%(a,b))
  5. return True
  6.  
  7. ret = name('nick','jenny','car')
  8. print(ret)
  9.  
  10. 输出结果:
  11. This is inner one before.
  12. This is inner one before angin.
  13. This is inner two before.
  14. This is inner two before angin.
  15. This is name.nick and jenny.
  16. This is inner two after.
  17. This is inner two after angin.
  18. This is inner one after.
  19. This is inner one after angin.
  20. True
  1.  

3.闭包

  1. '''
  2. 闭包:在一个作用域里放入定义变量,相当于打了一个包
  3. '''
  4. def father(name):
  5. def son():
  6. # name='alex'
  7. print('我爸爸是 [%s]' %name)
  8. def grandson():
  9. # name='wupeiqi'
  10. print('我爷爷是 [%s]' %name)
  11. grandson()
  12. son()
  13. father('舒克')

4.综合运用

  1. user_list=[
  2. {'name':'alex','passwd':''},
  3. {'name':'linhaifeng','passwd':''},
  4. {'name':'wupeiqi','passwd':''},
  5. {'name':'yuanhao','passwd':''},
  6. {'name':'病毒尖er','passwd':''},
  7. ]
  8. current_user={'username':None,'login':False}
  9.  
  10. def auth_func(func): # 用户登陆验证
  11. def bar(*args,**kwargs):
  12. if current_user["username"] and current_user["login"]:
  13. res = func(*args,**kwargs)
  14. return res
  15. for i in range():
  16. username = input("请输入用户名:").strip()
  17. passwd = input("请输入密码:").strip()
  18. for item in user_list:
  19. if username == item["name"] and passwd == item["passwd"]:
  20. current_user["username"] = username
  21. current_user["login"] = True
  22. res=func(*args,**kwargs)
  23. return res
  24. else:
  25. print("您输入的用户名或者密码有误")
  26. return bar
  27. @auth_func # 相当于index=auth_func(index)
  28. def index():
  29. print("欢迎来到京东商城" )
  30. @auth_func # 相当于home=auth_func(home)
  31. def home(name):
  32. print("%s欢迎回家" %name)
  33. @auth_func # 相当于shop_car=auth_func()
  34. def shop_car(name):
  35. print("%s的购物车是空的,赶紧购物咯" %name)
  36.  
  37. index()
  38. home(current_user["username"])
  39. shop_car(current_user["username"])
  1. user_list=[
  2. {'name':'alex','passwd':''},
  3. {'name':'linhaifeng','passwd':''},
  4. {'name':'wupeiqi','passwd':''},
  5. {'name':'yuanhao','passwd':''},
  6. {'name':'病毒尖er','passwd':''},
  7. ]
  8. current_user={'username':None,'login':False}
  9. def auth(auth_type="file"):
  10. def auth_func(func): # 用户登陆验证
  11. def bar(*args,**kwargs):
  12. if auth_type == "file":
  13. if current_user["username"] and current_user["login"]:
  14. res = func(*args,**kwargs)
  15. return res
  16. for i in range(): # 给用户三次重复输入的机会 防止进入其它功能进入下一层
  17. username = input("请输入用户名:").strip()
  18. passwd = input("请输入密码:").strip()
  19. for item in user_list:
  20. if username == item["name"] and passwd == item["passwd"]:
  21. current_user["username"] = username
  22. current_user["login"] = True
  23. res=func(*args,**kwargs)
  24. return res
  25. else:
  26. print("您输入的用户名或者密码有误")
  27. elif auth_type == "ldap":
  28. print("快点告诉你,你用我画的蜡笔")
  29. res = func(*args,**kwargs)
  30. return res
  31. return bar
  32. return auth_func
  33. @auth(auth_type="file")
  34. def index():
  35. print("欢迎来到京东商城" )
  36. @auth(auth_type="ldap") # 传参数 类型对应
  37. def home(name):
  38. print("%s欢迎回家" %name)
  39. @auth(auth_type="file")
  40. def shop_car(name):
  41. print("%s的购物车是空的,赶紧购物咯" %name)
  42.  
  43. index()
  44. home(current_user["username"])
  45. shop_car(current_user["username"])
  46.  
  47. 有参装饰器

二、代器 & 生成器

1、迭代器

  迭代器只不过是一个实现迭代器协议的容器对象。

迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)

特点:

  1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
  3. 访问到一半时不能往回退
  4. 便于循环比较大的数据集合,节省内存
  1. >>> a = iter([,,,,])
  2. >>> a
  3. <list_iterator object at 0x101402630>
  4. >>> a.__next__()
  5.  
  6. >>> a.__next__()
  7.  
  8. >>> a.__next__()
  9.  
  10. >>> a.__next__()
  11.  
  12. >>> a.__next__()
  13.  
  14. >>> a.__next__()
  15. Traceback (most recent call last):
  16. File "<stdin>", line 1, in <module>
  17. StopIteration #末尾生成StopIteration异常

2.1、生成器

  一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator);如果函数中包含yield语法,那这个函数就会变成生成器。

  生成器的概念:自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__方法),所以生成器就是可迭代对象

  1. def xran():
  2. print("one")
  3. yield
  4. print("two")
  5. yield
  6. print("sr")
  7. yield
  8.  
  9. ret = xran()
  10. #print(ret) #<generator object xran at 0x00000000006ED308>
  11.  
  12. result = ret.__next__()
  13. print(result)
  14.  
  15. result = ret.__next__()
  16. print(result)
  17.  
  18. result = ret.__next__()
  19. print(result)
  20.  
  21. # ret.__next__() #循环完毕抛出StopIteration
  22. #
  23. # ret.close() #关闭生成器

2.2.生成器表达式

  1. >>>a=[,,]
  2. >>>b=[i** for i in a]
  3. >>>b
  4. [, , ]
  5. >>>ib=(i** for i in a)
  6. >>>ib
  7. <generator object <genexpr> at 0x7f72291217e0>
  8. >>>next(ib)
  9.  
  10. >>>next(ib)
  11.  
  12. >>>next(ib)
  13.  
  14. >>>next(ib)
  15. Traceback (most recent call last):
  16. File "<stdin>", line , in <module>
  17. StopIteration

2.4补充1

  1. # 用生成器函数
  2. # yield 相当于return控制的是函数的返回值
  3. # x=yield的另外一个特性,接收send传过来的值,赋值给x
  4. def test():
  5. print("开始啦")
  6. first = yield # return first = None
  7. print("第一次",first)
  8. yield
  9. print("第二次")
  10. t = test()
  11. print(test().__next__())
  12. res = t.__next__() # next(t)
  13. print(res)
  14. res = t.send("函数停留在first那个位置,我就是给first赋值的")
  15. print(res)
  16.  
  17. 输出结果
  18. 开始啦
  19. None
  20. 开始啦
  21. None
  22. 第一次 函数停留在first那个位置,我就是给first赋值的

2.5补充于总结

1.yield--->自定义函数中只要出现y写了点就说明函数已经是一个Generator。

  • yield--->m=yield 5  131 可作为表达式进行赋值,此刻m的值是131,5是def定义的函数返回的值
  • yield--->next()   函数被调用后必须经过.__next__()方法执行,直到返回值StopIteration停止

2.send()与next()

  • send()与next()作用基本相同,但是send(*)可以产地yield的表达式值进入,而next()不能传递特定的值,只能传递None进去
  • 友情提醒:第一次调用时,请使用next()语句或是send(None),不能使用send发送一个非None的值,否则会出错的,因为没有yield语句来接收这个值

3.总结

优点:生成器使用yield语句返回一个值。yield语句挂起该生成器函数的状态,保留足够的信息,以便之后从它离开的地方继续执行

优点一:生成器的好处是延迟计算,一次返回一个结果。也就是说,它不会一次生成所有的结果,这对于大数据量处理,将会非常有用。

优点二:生成器还能有效提高代码可读性

注意事项:生成器只能遍历一次(母鸡一生只能下一定数量的蛋,下完了就死掉了)

四、python'中 for循环机制

  1.首先通过调用.__iter__()方法把他们变成可迭代对象

  2.之后for循环调用了__next__方法进行取值

  3.for循环会捕捉StopIteration异常,以终止迭代

返回:基础之函数

  

    

python修炼7----迭代器的更多相关文章

  1. Python基础之迭代器和生成器

    阅读目录 楔子 python中的for循环 可迭代协议 迭代器协议 为什么要有for循环 初识生成器 生成器函数 列表推导式和生成器表达式 本章小结 生成器相关的面试题 返回顶部 楔子 假如我现在有一 ...

  2. python修炼第一天

    Python修炼第一天 新的开始:不会Python的运维,人生是不完整的. 为了我的人生能够完整,所以我来了!今后跟着太白金星师傅学习功夫,记录一下心得,以便日后苦练. 一 Python的历史: Py ...

  3. python is、==区别;with;gil;python中tuple和list的区别;Python 中的迭代器、生成器、装饰器

    1. is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同 == 比较的是两个对象的内容是否相等 2. with语句时用于对try except finally 的优 ...

  4. python基础之迭代器协议和生成器

    迭代器和生成器补充:http://www.cnblogs.com/luchuangao/p/6847081.html 一 递归和迭代 略 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个ne ...

  5. python设计模式之迭代器与生成器详解(五)

    前言 迭代器是设计模式中的一种行为模式,它提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示.python提倡使用生成器,生成器也是迭代器的一种. 系列文章 python设计模 ...

  6. Python之路迭代器协议、for循环机制、三元运算、列表解析式、生成器

    Python之路迭代器协议.for循环机制.三元运算.列表解析式.生成器 一.迭代器协议 a迭代的含义 迭代器即迭代的工具,那什么是迭代呢? #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的 ...

  7. python基础8 -----迭代器和生成器

    迭代器和生成器 一.迭代器 1.迭代器协议指的是对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2. ...

  8. Python 拓展之迭代器

    写在之前 今天来讲讲「迭代器」的内容,其实已经拖了好多天了,感觉再不写就要忘记了.「迭代」相信对你来说已经不陌生了,我前面曾经专门用一篇文章来讲,如果你已经没有什么印象的话,就再点进去看看(零基础学习 ...

  9. 【Python基础】迭代器、生成器

    迭代器和生成器 迭代器 一 .迭代的概念 #迭代器即迭代的工具,那什么是迭代呢? #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单 ...

  10. Python - 三大器 迭代器,生层器,装饰器

    目录 Python - 三大器 迭代器,生层器,装饰器 一. 容器 二. 可迭代对象(iterable) 三. 迭代器 四. 生成器 五. 装饰器 1. 定义 六. 闭包 Python - 三大器 迭 ...

随机推荐

  1. Arduino 不同Arduino衍生板子的问题

    arduino IDE装上的时候,要记得在windows平台安装驱动. 如果不安装驱动的话,烧写程序的时候也许会遇到下面的现象. 原因有如下几种: 1,arduino控制板或者COM口没有选对,这种问 ...

  2. 内核操作系统Linux内核变迁杂谈——感知市场的力量

    本篇文章个人在青岛游玩的时候突然想到的...今天就有想写几篇关于内核操作系统的博客,所以回家到以后就奋笔疾书的写出来发表了 Jack:什么是操作系统? 我:你买了一台笔记本,然后把整块硬盘彻底格式化, ...

  3. Oracle全角和半角处理函数

    1.TO_MULTI_BYTE语法: TO_MULTI_BYTE(String) 功能: 计算所有单字节字符都替换为等价的多字节字符的String.该函数只有当数据库字符集同时包含多字节和单字节的字符 ...

  4. css透明度(兼容所有浏览器)

    .transparent{ background: rgba(, , , 0.3) !important; /* IE无效,FF有效 */ filter: alpha(opacity=); -moz- ...

  5. Curator Recipes(Cache&Counter)

    Cache 路径缓存(Path Cache) 监视一个ZNode,当子节点增加.更新.删除改变状态时,路径缓存会在本地保存当前子节点及其数据和状态. public PathChildrenCache( ...

  6. Fiddler捕获抓取 App端数据包

    最近项目设计到App抓包,所以采用Fiddler工具来采集获取APP数据包,但是fiddler对有些app是无法捕获到数据包的,以下是我的处理方法: 1. 我默认代理端口使用的是自定义的端口而不是默认 ...

  7. [SQL基础教程] 4-4 事务

    [SQL基础教程] 4 数据更新 4-4 事务 事务 需要在同一处理单元中执行的一系列更新处理的集合 创建事务 事务开始语句; DML语句1; DML语句2; . . . 事务结束语句; 事务开始语句 ...

  8. node-canvas

    1.使用之前需要预先安装  Cairo 本人安装遇到各种各样的坑,可以参考这里来填坑:https://github.com/Automattic/node-canvas/wiki/Installati ...

  9. js时间戳转换时间格式

    function getLocalTime(time){ if(time > 0){ var dateStr = new Date(time * 1000); var str = "& ...

  10. scip习题(1) scheme和c实现的对比

    习题1.3 定义一个过程,它以三个数为参数,返回其中较大的两个数的平方和. (Define a procedure thats three numbers as argument and return ...