装饰器和生成器和迭代器

一. 装饰器:

  (1)本质是函数,完成特定的功能,装饰其他函数,为其他函添加附加功能

  (2)装饰器的原则:1.不能修改被装饰的函数的源代码

         2.不能修改被装饰的函数的调用方式

  (3)实现装饰器要掌握的方法,1.函数即变量。2.高阶函数。3.函数嵌套。

#函数即变量
x=1
def test():
    #函数体
    pass
在这里,x是一个变量,而test函数可疑看出test = 函数的函数体
即可以将x传进某个函数,也可以将函数当作变量传进其他的函数

函数即变量
#高阶函数的原则:
        1.把一个函数名当作实参传进其他函数
        2.返回值中包含函数名
#什么是把一个函数名当作实参传进其他函数
def bar():
    print("in the bar")

def test(func):
    print(fun)
    func()

test(bar)
输出结果是:bar的内存对象地址 和 “in the bar”
#什么是返回值中包含函数名
def test(func):
    print(func)
    return func

def bar():
    print("in the bar")
情况一:
test(bar) 输出结果是,bar的内存对象地址
情况二:
print(test(bar)) 的输出结果是, 两个bar的内存对象地址,完全相同
情况三:
test(bar()) 输出结果是,“in the bar”和 None
print(test(bar()))#输出三个值“in the bar,None,None”,因为test(bar())里面返回print(bar())和bar()
print(print(bar()))#输出“in the bar,None”因为没有return值,所以后面会返回none

  什么是嵌套函数:即在一个函数的函数体内申明另一个函数,而不是在外面创建,再在体内调用

#嵌套函数
def  bar():
    def  func():
        pass

而不是
def  func():
        pass
def  bar():
        func()

  (4)其中高阶函数+函数嵌套=装饰器

#装饰器
import time

def timer(func):
    def deco():
        start_time=time.time()
        func()
        stop_time=time.time()
        print("the func run time is :%s"%(stop_time-start_time))
    return deco

def test1():
    time.sleep(1)
    print("in the test1")

@timer#@timer其实相当于test2=timer(test2)这一步
def test2():
    time.sleep(1)
    print("in the test2")

print(timer(test1))
#输出<function timer.<locals>.deco at 0x01408780>
#因为return deco,》》》print(deco),输出内存对象


test1=timer(test1)
test1()#相当于调用deco()
#输出
#in the test1
#the func run time is :1.0000569820404053


test2()
#输出
#in the test2
#the func run time is :1.0000574588775635

 

二,生成器(generator)

  什么是生成器:就是我们可疑通过列表生成式直接创建一个列表(list=[x*x for x in range(10)]   >>print(list)>>[0,1,2,4,9,16,25,36,49,.....]),但是受内存限制。列表是内容时有限的,而且创建一个包含100万个元素时,不仅占用很大,如果我们仅需访问几个元素,那会造成很大的数据浪费

  所以,列表元素可疑按照某种算法推算出来,需要多少就通过算法继续推算多少处理,这种一边循环一边计算的机制,称为generator生成器

(1).原则:1.生成器只有在调用时才能生成相应的数据  2.只记录当前位置,只有__next__()方法

(2).生成器的创建:

    生成器和生成式的区别在于最外层的[]还是(),[]是list,()是generator

  g=(x*x for x in range(10)) >>print(list)>>输出一个内存对象,这里表示生成器是调用时才产生值,而列表是一创建就有值,不需根据调用才生成。

那我们如何查看生成器的值呢?我们可以通过__next__()方法

  print(g.__next__())#表示访问下一个元素数据,只能获取当前生成或下面的数据,上面的的数据是不记录的,无法获取

  

三.迭代器(iterable)

  (1)可以直接作用于for循环:这些可以直接作用于for循环的对象称为可迭代对象(iterable)

    集合数据:list,tuple, dict, set ,str

    generator:生成器和带yield的generator函数

 

  (2)可以被next()函数调用并不断返回下一个值的对象称为迭代器(iterator)

    生成器都是iterator对象,但list,tuple, dict, set 虽然是iterable对象,却不是iterator对象

    将list,tuple, dict, set 变成iterator对象,可以通过iter()函数

  (3)我们可以通过isinstance()方法判断一个对象是否是iterable对象还是iterator对象

    isinstance( {},iterable)>>输出True则为iterable对象

    

Python的iterator表示一个数据流,for循环本质上的通过不断调用next()函数来实现的

(1for i in [0,1,2,3,4,5,6,7,8,9]:
    print(i)

(2)  
it=iter([0,1,2,3,4,5,6,7,8,9])
while True:
    try:
        x=next(it)
        print(x)
    except StopIteration:
        break#表示遇到StopIteration就停止,即循环到最后一个就停止    
1)等价于(2),(2)是(1)的本质

 

posted @ 2017-09-02 23:41  咸鱼功阀术  阅读(240)  评论(0编辑  收藏  举报