Python 全栈开发五 迭代器 生成器 装饰器

一、迭代器

迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter() 和 next()

字符串,列表或元组对象都可用于创建迭代器,生成迭代器的方法是iter():

>>li = [1,2,3,4,5]
>>it = iter(li)     #生成一个迭代器
>>it.__next__()
1
>>next(it)  #以上两种next都可以使用
2
>>for i in it:
        print(i)
3
4
5
#迭代完毕后,迭代器里面的数据就没有了
>> type(it)
<class ‘list_iterator‘>   #类型是迭代器类型

二、生成器

在描述生成器前我们先来了解列表生成式:

#普通定义的列表直接把列表写死
li = [1,2,3,4,5]

#使用列表生成式,可以为列表添加一些新的属性

li1 = [a*a for a in range(10)]
print(li1)

#也可以用以下两种方法方法

li2 = list(map(lambda x:x+1,li))
print(li2)

a = []
for i in range(10):
    a.append(i+1)
print(a)

#从以上对比可以看出,使用第二种方法代码最为简单,即列表生成式

  虽然有列表生成式,可以简化生成特定列表的操作,但是当列表数据过大,就会过度的消耗内存,并且列表是数据也不会一直使用,在python中有一种一边循环一边计算的机制就是生成器。

生成器的第一种表现形式:

#创建一个生成器

li = (a*a for a in range(10))

print(li) #<generator object <genexpr> at 0x00000000027BD468>,返回一个生成器对象,用next调用对象
print(li.__next__())
print(next(li))  #且只能调用一次,不能往回调用

‘‘‘我们讲过,generator保存的是算法,每次调用next(g),
就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,
抛出StopIteration的错误。一般情况下,我们用for循环来调用全部数据‘‘‘

for i in li:
    print(i)

生成器的第二种表现形式:

  生成器:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。调用一个生成器函数,返回的是一个迭代器对象。

  yield语法:每当行数运行到yield是就会中断并且保存当前所有的运行信息,并且在执行next()方法后继续从中断的地方运行。

#生成一个斐波拉契数列
def fib(max):
    a,b,n = 0,0,1
    while n < max:
        a, b = b,a+b
        n +=1
    return ‘done‘

c = fib(5)
print(c)
#弊端,会直接全部生成

#把该函数变为一个生成器
def fib2(max):
    a,b,n = 0,0,1
    while n < max:
        yield b    #遇到一次返回一次,再次激活则运行后面的代码,用next激活
        a, b = b,a+b
        n +=1

d = fib2(5)
print(next(d))

下面是一个利用yield实现的一种单线程下的并发效果,也可以理解为一协程(后面会讲这一内容):

import time

def consumer(name):
    print(‘%s准备吃包子了!‘ % name)
    while True:
        baozi = yield               # 保存当前状态的值,并且退出函数
        print(‘包子[%s]来了,被[%s]吃了!‘% (baozi,name))

# c = consumer(‘alix‘)   生成一个生成器对象
# c.__next__()        调用生成器

def producer():
    c = consumer(‘a‘)
    c2 = consumer(‘b‘)
    c.__next__()
    c2.__next__()
    print(‘老子开始准备做包子了‘)
    for i in range(10):
        time.sleep(1)
        print(‘做了1个包子,分两半‘)
        c.send(i)               #给yield传值,并且唤醒yield
        c2.send(i)
producer()

三、装饰器

装饰器:本质上就是函数,作用就是为其他函数添加其他功能原则:1、不能修改被装饰的函数的源代码     2、不能修改被修饰函数的调用方式

在将装饰器前我们进行一些装饰器的知识储备:

1.函数即‘变量‘2.高阶函数    1.把一个函数名当做实参传给另一个函数(添加功能不修改函数的源代码)    2.返回值中包含函数名(不修改函数的调用方式)3.嵌套函数

函数即“变量”:

函数定义好后就像变量一样存储在内存中,当我们去调用的时候才会有意义。

#函数即变量

# def foo():
#     print(‘in the foo‘)
# foo()

#即无需考虑函数的定义顺序,就和定义变量一样

def bar():
    print(‘in the bar‘)
def foo():
    print(‘in the foo‘)
    bar()
foo()

高阶函数:即把一个函数名当做实参传递给函数,就类似有把一个变量名传递给函数。

# 高阶函数:把一个函数名,当做实参传给函数
import time
def bar():
    time.sleep(3)    #暂停3秒
    print(‘in the bar‘)

def text1(fun):
    start_time = time.time()   #起始时间
    fun()
    stop_time = time.time()    #结束时间
    print(‘the fun time is %s‘ % (stop_time-start_time))  #计算出fun()所用的时间

text1(bar)  #将该函数名传递进去

def bar2():
    time.sleep(3)
    print(‘in the bar2‘)

def text2(fun):
    print(fun)
    return fun

bar2 = text2(bar2)
bar2()

通过高阶函数的作用可以看出:在不改变函数的源代码的情况下,给函数增加了计时的功能

嵌套函数:

def foo():
    print(‘in the foo‘)
    def bar():
        print(‘in the bar‘)
    bar()
foo()

结合以上三种实现装饰器:

import time
def timer(func): #timer(text1)   func=text1    装饰器函数
    def wrapper(*args,**kwargs):
        start_time = time.time()
        func()              #run text1
        stop_time = time.time()
        print(‘the fun run time is %s‘ % (stop_time-start_time))
    return wrapper

@timer   # text1 = timer(text1)  这一步就是把text1传入timer
def text1():
    time.sleep(1)
    print(‘the is text1‘)

text1()

带参数的装饰器:

user,passwd = ‘alex‘,‘1234‘

def auth(outh_type):
    print(‘auth func:‘,outh_type)
    def outh_wrapper(func):
        def wrapper(*args,**kwargs):
            print(‘wrapper func args:‘,*args,**kwargs)
            if outh_type == ‘local‘:
                username = input(‘Username:‘.strip())
                password = input(‘Password:‘.strip())
                if user == username and passwd == password:
                    print(‘\033[32;1mUser has passed authentication\033[0m‘)
                    res = func(*args,*kwargs)
                    print(‘-- after authentication‘)
                    return res
                else:
                    exit("\033[31;1mInvalid username or password\033[0m")
            elif outh_type == ‘ldap‘:
                print(‘搞毛线‘)

        return wrapper
    return outh_wrapper

@auth(outh_type=‘local‘)
def index():
    print(‘welcom to index page‘)

index()

http://www.cnblogs.com/wupeiqi/articles/4980620.html

原文地址:https://www.cnblogs.com/wallacewang/p/8860363.html

时间: 2024-12-22 07:27:40

Python 全栈开发五 迭代器 生成器 装饰器的相关文章

Python全栈开发之8、装饰器详解

一文让你彻底明白Python装饰器原理,从此面试工作再也不怕了. 一.装饰器 装饰器可以使函数执行前和执行后分别执行其他的附加功能,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),装饰器的功能非常强大,但是理解起来有些困难,因此我尽量用最简单的例子一步步的说明这个原理. 1.不带参数的装饰器 假设我定义了一个函数f,想要在不改变原来函数定义的情况下,在函数运行前打印出start,函数运行后打印出end,要实现这样一个功能该怎么实现?看下面如何用一个简单的装饰器来实现

python全栈学习总结六:装饰器

一 装饰器定义 装饰器:本质就是函数,一种增加函数或类的功能的简单方法,它可以快速的给不同的函数或者类插入相同的功能. 原则:(1)不修改被修饰函数的源代码.    (2)不修改被修饰函数的调用方式 装饰器 = 高阶函数+函数嵌套+闭包 #装饰器 = 高阶函数+函数嵌套+闭包 #高阶函数:输入或返回参数为函数 #函数嵌套中再定义函数 #闭包:函数中变量全部由函数内部提供 import time #为函数添加功能:计算函数的执行时间 def calc(num): res = 0; for i in

Python全栈开发之---迭代器、可迭代对象、生成器

1.什么叫迭代 现在,我们已经获得了一个新线索,有一个叫做"可迭代的"概念. 首先,我们从报错来分析,好像之所以1234不可以for循环,是因为它不可迭代.那么如果"可迭代",就应该可以被for循环了. 这个我们知道呀,字符串.列表.元组.字典.集合都可以被for循环,说明他们都是可迭代的. 我们怎么来证明这一点呢? 1 from collections import Iterable 2 3 l = [1,2,3,4] 4 t = (1,2,3,4) 5 d =

Python全栈开发之目录

基础篇 Python全栈开发之1.输入输出与流程控制 Python全栈开发之2.运算符与基本数据结构 Python全栈开发之3.数据类型set补充.深浅拷贝与函数 Python全栈开发之4.内置函数.文件操作和递归 Python全栈开发之5.几种常见的排序算法以及collections模块提供的数据结构 Python全栈开发之6.正则表达式 Python全栈开发之7.模块和几种常见模块以及format知识补充 Python全栈开发之8.装饰器详解 Python全栈开发之9.面向对象.元类以及单例

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全栈开发目录

python全栈开发目录 linux命令 初识python python基础数据类型 函数编程.set.深浅拷贝 内置函数 文件操作 装饰器 迭代器和生成器 常用模块 初识类和对象 类和对象(进阶) 反射 异常处理 socket.IO多路复用 线程.进程.协程 HTML CSS JavaScript DOM文档操作 jQuery实例 web框架本质 Tornado mysql基础 mysql进阶 ..... 基本算法 递归--二分法查找 冒泡排序 更多 线程池

Python 全栈开发【第一篇】:目录

Python 全栈开发[第0篇]:目录 第一阶段:Python 开发入门 Python 全栈开发[第一篇]:计算机原理&Linux系统入门 Python 全栈开发[第二篇]:Python基础语法入门 Python 全栈开发[第三篇]:数据类型.字符编码.文件操作 第二阶段:函数编程&常用标准库 Python 全栈开发[第四篇]:函数.递归.生成器.迭代器 Pyhton 全栈开发[第五篇]:常用模块学习 第三阶段:面向对象编程&网络编程基础 Python 全栈开发[第六篇]:面向对象

Python全栈开发【第一篇】:初识Python

Python全栈开发[第一篇] 本节内容: Python 的种类 Python 的环境 Python 入门(解释器.编码.变量.input输入.if流程控制与缩进.while循环) if流程控制与while循环练习题 基本数据类型前引 Python 的种类 Cpython Python的官方版本,使用C语言实现,使用最为广泛,CPython实现会将源文件(py文件)转换成字节码文件(pyc文件),然后运行在Python虚拟机上. Jyhton Python的Java实现,Jython会将Pyth

Python全栈开发

Python全栈开发 一文让你彻底明白Python装饰器原理,从此面试工作再也不怕了. 一.装饰器 装饰器可以使函数执行前和执行后分别执行其他的附加功能,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),装饰器的功能非常强大,但是理解起来有些困难,因此我尽量用最简单的例子一步步的说明这个原理. 1.不带参数的装饰器 假设我定义了一个函数f,想要在不改变原来函数定义的情况下,在函数运行前打印出start,函数运行后打印出end,要实现这样一个功能该怎么实现?看下面如何用