python【5】迭代,生成,修饰

不问归期 提交于 2019-12-03 01:49:40

迭代器

迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件

特点:

  1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
  3. 访问到一半时不能往回退
  4. 便于循环比较大的数据集合,节省内存
from collections import Iterator
# isinstance()  判断是否是 迭代器# 可以被next()函数不断返还下一个值的被称为迭代器# iter()  可以将 list dict str 编程迭代器

生成器generator

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

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# By   Garrett

a = [i*2 for i in range(10)]

print(a)

# 生成器

# g = (i*2 for i in range(10))
#
# print(g)
#
# for i in g:
#     print(i)
#

# 生成器只记住当前位置  只有一个 __next__()  方法
'''
def fib(max):
    n,a,b = 0,0,1
    while n<max:
        print(b)
        a,b = b,a+b
        n = n+1
    return 'ok'

fib(10)
'''
# 将这个函数改成生成器  将 print 改成 yield 即可
def fib(max):
    n,a,b = 0,0,1
    while n<max:
        yield b
        a,b = b,a+b
        n = n+1
    return 'ok'

f = fib(10)
print(f.__next__())


# 如果你取得次数超过这个函数生成的个数,那么return 的结果 会作为异常抛出

这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。

另外,还可通过yield实现在单线程的情况下实现并发运算的效果

#  生成器可以用来实现 单线程下的并行效果

#  生成器可以用来实现 单线程下的并行效果
import time

def consumer(name):
    print('%s  要来吃包子了' %name)
    while True:
        baozi = yield

        print('包子 %s 来了,被 %s 吃了 ' %(baozi,name))
'''
c = consumer('A')  是一个生产器  但是yield 没有值
c.__next__()  会让生成器执行到yield 并暂停
c.send(i)  会让生成器继续执行到下一次yield 处  并给yield赋值   
'''

def producer(name):
    c = consumer('A')
    c2 = consumer('B')
    c.__next__()
    c2.__next__()
    for i in range(10):
        time.sleep(1)
        print('生产了1波包子')
        c.send(i)
        c2.send(i)

producer('jack')

装饰器

直接 看银角大王写的文档 http://www.cnblogs.com/wupeiqi/articles/4980620.html  

# 装饰器:本质是函数,用来装饰其他函数,就是为其他函数添加附加功能
#
# 原则  1 不能修改被装饰函数的源代码    2 不能修改被装饰函数的调用方式
#函数就是变量  高阶函数+嵌套函数 = 装饰器

import time

def timmer(func):
    def warpper(*args,**kwargs):
        start_time = time.time()
        func()
        stop_time = time.time()
        print('the func run time is {}'.format(stop_time-start_time))
    return  warpper

@timmer
def test1():
    time.sleep(3)
    print('in the test1')
    return 0

test1()
import time

#1 高阶函数  把函数当做变量传入

#2  返回值是函数名


def bar():
    time.sleep(2)
    print('i am bar')

# def timmer(func):
#     start = time.time()
#     func()
#     stop = time.time()
#     print('func run time is %s' %(stop-start))
#
# timmer(bar)

#上面解决了装饰器的第一个需求 没有改变源函数的代码  但是改变了调用方式

'''
def wapper(func):
    start = time.time()
    func()
    stop = time.time()
    print('func run time is %s' %(stop-start))
    return func
'''
#print(wapper(bar))
# return函数名 得到的是内存地址     韩书即变量  得到内存地址可以直接调用

# bar = wapper(bar)
# bar()  # 但是会导致 bar函数 运行了两遍

#嵌套函数  在一个函数体内声明一个函数
# def foo():
#     def bar():
#         print('i am bar')
#     bar()




def timmer(func):
    def wapper(*args,**kwargs):
        start = time.time()
        func(*args,**kwargs)
        stop = time.time()
        print('func run time is %s' % (stop - start))
    return wapper

@timmer   #test = timmer(test)
def test():
    time.sleep(1)
    print('i am test')

#test = timmer(test)

test()

# 当一个修饰器需要修饰多个函数的时候 如果 有的函数有参数 有的函数没有参数 那么  在修饰器中定义的函数就需要是不定参数的
@timmer
def test2(name):
    time.sleep(1.5)
    print('name is {}'.format(name))

test2('jack')


#如果  函数本身 有返回值   之前的方式 则无法得到返回值

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!