python -- 迭代器和装饰器

迭代器和装饰器在python中的使用十分常见,下面是个人对迭代器和装饰器的理解

迭代器

  1、迭代器 iter 的特点:

    (1).访问者不需要关心迭代器的内部结构,仅需要通过__next__()方法不断去取下一个内容
    (2).不能随机访问集合(不是set,只是一些元素的聚集体)中的某个值,只能从头到尾依次访问
    (3).访问到一半时不能后退(过去的就过去了,不能回头)
    (4).便于循环比较大的数据集合,节省内存(每次需要了指定数据时,才把该读取到内存中,eg:迭代文件时,内存中每一时刻都只有文件的一行)

1 a = iter([‘root‘,‘admin‘,‘python‘,‘ruby‘ ])    #生成一个迭代器
2 print(a.__next__())
3 print(a.__next__())      #只有一个__next__() 方法
4 print(‘waitting!‘)    #在第二代的过程中,能停下来做其他的事
5 print(a.__next__())
6 print(a.__next__())
7 #print(a.__next__())    #报错 超出迭代器范围

  常见迭代器使用:
    读文件时:
      with open(‘a*.txt‘,‘r+‘) as f:
        for line in f:
        ...
    这里的for i in f:就是用的迭代器,避免依次把文件内容全部读取到内存中,节省内存。

在介绍迭代器时,还有个概念要明白,何为生成器

  生成器 generator
  定义: 一个函数调用时返回一个迭代器,那么这个函数就叫做生成器,如果函数中包含了yield语法,那么这个函数就会变成一个生成器(保存函数的中断状态)

 1 >>>
 2 >>> def test_yeild(n):
 3     while n > 0:
 4         n -= 2
 5         yield 10
 6         print(‘注意何时打印这句话...‘)
 7
 8
 9 >>> t = test_yeild(12)      # 与普通函数不同,这里只是生成一个迭代器,不会跳到‘函数体’里面去(执行函数体),而是等待迭代器的__next__()方法
10 >>> t.__next__()
11 10                # 返回yield后面的值,并在执行完yield后 暂停程序 ,等待下一次__next__(),然后接着从暂停的地方开始运行
12 >>> t.__next__()
13 注意何时打印这句话...
14 10
15 >>> t.__next__()
16 注意何时打印这句话...
17 10
18 >>> t.__next__()
19 注意何时打印这句话...
20 10
21 >>> t.__next__()
22 注意何时打印这句话...
23 10
24 >>> t.__next__()
25 注意何时打印这句话...
26 10
27 >>> t.__next__()
28 注意何时打印这句话...
29 Traceback (most recent call last):
30   File "<pyshell#162>", line 1, in <module>
31     t.__next__()
32 StopIteration
33 >>> 

yield 可以返回一个值,也可以接收一个值,给yield传值用send()

看下面例子,用yield做了个简单的异步操作:

 1 import time
 2
 3 def consumer(name):
 4     print("%s 准备吃包子啦!" %name)
 5     while 1:
 6         baozi = yield
 7         print("包子[%s]来了,被[%s]吃了" %(baozi,name))
 8
 9 def producer(name):
10     c = consumer(‘A‘)
11     c2 = consumer(‘B‘)
12     c.__next__()
13     c2.__next__()
14     print("%s开始准备做包子啦!" %name)
15     for i in range(3):
16         time.sleep(1)        #执行时为了更清楚的看到过程
17         print("做了2个包子")
18         c.send(i)
19         c2.send(i)
20
22 producer(‘root‘)
A 准备吃包子啦!
B 准备吃包子啦!
root开始准备做包子啦!
做了2个包子
包子[0]来了,被[A]吃了
包子[0]来了,被[B]吃了
做了2个包子
包子[1]来了,被[A]吃了
包子[1]来了,被[B]吃了
做了2个包子
包子[2]来了,被[A]吃了
包子[2]来了,被[B]吃了

  

 1 def account(money):
 2     while money > 0:
 3         out_money = yield
 4         money -= out_money
 5         #yield 300
 6         print(‘又来取钱了!取了%s‘ %out_money)
 7
 8 atm = account(1500)
 9 atm.__next__()
10 for i in range(5):
11     atm.send(300)
12     #在第一次用__next__()方法启动迭代器后,每次调用迭代器,就会自动执行__next__()方法
13     

装饰器

  装饰器基本功能:对已有函数进行扩展

  (个人初步理解,可能错误)
  装饰器执行过程:
    1.在调用被装饰器装饰的函数时,先把被装饰器装饰的函数(装饰器下一行代码中函数)的函数名传递给装饰器从内到外第二层定义的函数
    2.把被装饰器装饰的函数的实参传递给装饰器最内层函数
    3.在装饰器内部实现被装饰器装饰的函数的调用

 简单装饰器:

 1 def login(func):
 2     def inner(*args,**kwargs):
 3         print("我是做身份验证的,验证成功才能调用函数")
 4         print(args,kwargs)
 5         func(*args,**kwargs)
 6         #return func(*args,**kwargs)
 7     return inner
 9     #若传进来的是函数名,那么没有执行‘()‘的话,即是函数的内存地址
10
11 #@login    #(装饰器)程序一执行,就会调用装饰器的函数
12 def home(name):
13     print("welcome [%s] vidited the home page" %name)
14
15 @login   #@符号的作用: 相当于执行 tv = login(tv)
16 #def tv(name,passwd=123):
17 def tv(*args,**kwargs):
18     print("welcome [%s] vidited the tv page" %args )
19     #若这里有返回值,则仅需要在inner里面返回函数结果
20 #@login
21 def movices(name):
22     print("welcome [%s] vidited the movices page" %name)
23
24 tv(‘root‘)
25 tv(‘xtsec‘,passwd=123)

复杂装饰器:

 1 ‘‘‘
 2 调用装饰器时(eg:@login(f1,f2)),传递多个参数的装饰器(三层装饰器)
 3 ‘‘‘
 4 def before():
 5     print("执行要装饰的函数之前执行")
 6
 7 def affter():
 8     print("执行要装饰的函数之后执行")      #没有return的函数默认返回None
 9
10 def test_ge(before1,affter1):
11     def login(func):
12         def inner(*args,**kwargs):
13             result_before = before1()
14             if(result_before != None):
15                 return ‘执行before条件未成功!‘    #这里运行就表示before函数没有正确运行结束,所以表示验证没通过
16             ret = func(*args,**kwargs)
17             if(ret != None):
18                 return ‘执行被修饰函数不成功!‘    #若前面验证通过,且装饰器正确执行,到这里整个装饰器运行结束
19             result_afftr = affter1()
20             if(result_afftr != None):
21                 return ‘执行时不满足要求!‘     #若前面装饰器修身的函数没正确运行,就会到这里,常用来返回错误信息
22             return ret
23         return inner
24     return login
25
26 def home(name):
27     print("welcome [%s] vidited the home page" %name)
28
29 ‘‘‘
30 接下来这一行有三个操作:
31 1.调用函数 test_ge(before, affter)
32 [email protected]   login为调用test_ge(before, affter)的返回值
33 3.新tv = inner    login()的返回值
34 ‘‘‘
35 @test_ge(before, affter)
36 def tv(*args,**kwargs):
37     print("welcome [%s] vidited the tv page" %args )
38     return 1
39
40 def movices(name):
41     print("welcome [%s] vidited the movices page" %name)
42
43
44 tv(‘root‘,passwd=‘admin‘)
45     #在这里执行tv()时,事实上时执行新的tv(),即是inner()
46 a = before()
47 print(type(a),a)
48 if a == None:
49     print(‘110‘)

在日常使用中,一般就用普通的装饰器,复杂度这个最好明白运行原理即过程

时间: 2024-10-31 00:33:41

python -- 迭代器和装饰器的相关文章

Python 迭代器&amp;生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发

本节大纲 迭代器&生成器 装饰器  基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致 迭代器&

python 迭代器 生成器 装饰器

迭代器 可以直接作用于for循环的对象统称为可迭代对象(Iterable). 可以被next()函数调用并不断返回下一个值的对象称为迭代器(Iterator). 所有的Iterable均可以通过内置函数iter()来转变为Iterator. names = iter(['sun', 'ibm', 'sunny']) print(names) print(names.__next__()) print(names.__next__()) print(names.__next__()) print(

Day4 - Python基础4 迭代器、装饰器、软件开发规范

Python之路,Day4 - Python基础4 (new版) 本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需求,看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],我要求你把列表里的每个值加1,你怎么实现?你可能会想到2种方式 >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>

Python_Day5_迭代器、装饰器、软件开发规范

本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 1.列表生成式,迭代器&生成器 列表生成 >>> a = [i+1 for i in range(10)] >>> a [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访

python学习笔记--装饰器

1.首先是一个很无聊的函数,实现了两个数的加法运算: def f(x,y): print x+y f(2,3) 输出结果也ok 5 2.可是这时候我们感觉输出结果太单一了点,想让代码的输出多一点看起来不这么单调: def showInfo(fun): def wrap(x,y): print "The function before" func(x,y) print "The function after" return wrap def f(x,y): print

1.16 Python基础知识 - 装饰器

Python中的装饰器就是函数,作用就是包装其他函数,为他们起到修饰作用.在不修改源代码的情况下,为这些函数额外添加一些功能,像日志记录,性能测试等.一个函数可以使用多个装饰器,产生的结果与装饰器的位置顺序有关. 装饰器基本形式: @装饰器1 def 函数1: 函数体 相当于:==> 函数1 = 装饰器1(函数1) 装饰器特点: 1.不修改源代码的调用方式 2.不修改源代码内容 3.装饰器有高阶函数与递归函数相融合的特点 多个装饰器修饰,示例: @foo @spam def bar():pass

ZMAN的学习笔记之Python篇:装饰器

年前工作事务比较繁琐,我只能用零碎的时间继续学习Python,决定开一个系列的博文,作为自己深入学习Python的记录吧.名字也取好了,就叫<ZMAN的学习笔记之Python篇>~开篇是关于装饰器的,春节假期码的字哈哈~就让我们开始吧! 本文的例子都是自己想的,如果不是很合适,请大家提出宝贵意见哈~谢谢啦! 一.为什么要用“装饰器” 比如我们写了如下一段代码: # 打印0~99 def func(): for i in range(100): print(i) 我们想要监测执行这个函数花费了多

六、PYTHON 学习之装饰器使用

Python是一种强大的语言,即可浅尝辄止,也可深入挖掘.很适合做科学计算.数据挖掘等等.今天我将简单介绍一下Python的装饰器(Decorators)的用法 . 假设我们想要庆祝下生日,需要邀请一些朋友过来参加.但是你有个讨厌的朋友,叫Joe,必须不能让他来啊.可能首先你想到的是建一个list,然后迭代查找并移除所有的Joe童鞋.这当然是个好方法,但是这里为了介绍装饰器,我们会用@来完成这个工作.虽然可能看起来没有什么必要,但是有助于大家学习装饰器的用法. 首先创建一个Python文件app

python高级之装饰器

python高级之装饰器 本节内容 高阶函数 嵌套函数及闭包 装饰器 装饰器带参数 装饰器的嵌套 functools.wraps模块 递归函数被装饰 1.高阶函数 高阶函数的定义: 满足下面两个条件之一的函数就是高阶函数: 接受一个或多个函数作为输入参数 输出一个函数 首先理解一个概念:函数名其实也是一个变量,一个函数其实就是一个对象,函数名就是对这个对象的引用.所以函数名也就和一个普通变量一样可以被当做函数的变量进行传递,当然也能够把函数名当做一个变量进行返回. 举个栗子: 1 def foo