7 Python 基础 装饰器 生成器 迭代器

本节内容:

  1. 装饰器    介绍    参数 

  2. 生成器    介绍   创建      实现 斐波拉契数列

  3. 迭代器    介绍   判断是不是迭代器对象      for循环内部做的三件事

装饰器 :(函数)拓展原来还是功能的一种函数,好出就是在不用改原函数代码的前提下给函数增加新的功能。

       也就是说 添加新的功能在函数上。

      @符号是装饰器的语法糖,在定义函数的时候使用,避免一次赋值操作。

     举个列子 老板 写了两个简单的函数 foo()   bar()  在不改原代码的基础上计算一下  他们执行了多长时间。

  为里执行效果  好看  用time,sleep(2)暂停了 两秒

import time  #时间模块



def show_time(f):

    def inner():
        start = time.time()
        f()

        time.sleep(2)

        end = time.time()

        print('spend %s'%(end - start))

    return inner


@show_time    #@方法  foo = show_time(foo)

def foo():
    print('foo......')


#foo()#可以直接执行


@show_time#      bar = show_time(bar)
def bar():
    print('bar.....')


bar()

  装饰器  参数  

     顺序参数

#顺序参数

import time

def show_time(f):
    def inner(x,y):
        start = time.time()
        f(x,y)
        end = time.time()
        print('spend %s'%(end - start))
    return inner


@show_time

def add(a,b):
    print(a + b)
    time.sleep(1)
add(1,2)

  

不定长参数

 

import time
def show_time(f):
    def inner(*x):
        start = time.time()
        f(*x)
        end = time.time()
        print('spend %s'%(end - start))
    return inner


@show_time

def add(*a):
    wk=0
    for i in a:
        wk +=i
    print(wk)
    time.sleep(1)
add(1,2,3,5,6,7,7)

 

  功能函数加参数

import time
def logger(flag):
    def show_time(f):
        def inner(*x,**y):
            start = time.time()
            f(*x,**y)
            end = time.time()
            print('spend %s'%(end - start))
            if flag == 'true':
                print('日志记录')
        return inner
    return show_time

@logger('true')#想添加日志记录    写true  不像添加 随变写什么

def add(*a,**b):
    wk=0
    for i in a:
        wk +=i
    print(wk)
    time.sleep(1)
add(1,2,3,5,6,7,7)

  

2  生成器

        什么是生成器 ,通过列表生成式 ,我们可以直接创建一个列表。但是受到内存限制,列表的容量肯定是有限的,而且创建一个包含100万元素的列表,不仅占用空间大,如果我们只访问前面几个元素   后面的空间就白白浪费了,如果列表元素可以通过某种推算出来,那我们就可以通过不断的循环推算出后续的元素,从而节省大量的空间

 

在Python中,一遍循环一边计算的机制 称为生成器:generator 

生成器有两种创建方式 :

                                      1    f = (x*2 for x in range(5))    ()括号

                                                2   yield    关键字

 

简单的创建  第一种

f = (x*2 for x in range(5))     #创建生成器    循环x 然后乘2    依次打印
print(f)
print(next(f))#等价于 f. __next__()    下划线
print(next(f))
print(next(f))
print(next(f))#只能一个一个的取
print(next(f))

  

 

  生成器就是一个可迭代对象

#生成器就是一个可迭代对象(Ietrable)
f = (x*2 for x in range(5))
for i in f:
    print(i)

  

第二种

   #已经不是一个函数了  已经成了生成器对象了  没有进去
   #只要有yield就是生成器对象、foo()  是生成器对象
def foo():
    print('ok')
    yield 1

foo()


#通过next进去
def foo():

    print('ok')
    abc = yield 1
    print(abc)

    print('ok2')
    yield 2

g = foo()
a = next(g)  #可以返看回值的
print(a)

g.send('eee')

#第一次进入不能用send  因为不知道进去传值给谁  可以传入值None
#send 和next都可以进入生成器   不同的是send 可以给里面传值

  实现斐波拉契数列 

 #斐波拉契数列
def fib(max):
    n,a,b = 0,0,1
    while n < max:
        yield b
        a,b = b,a+b

        n = n + 1


for i in fib(10):
    print(i)

  迭代器:

      生成器都是迭代器  迭代器不一定是生成器

    迭代是访问集合元素的一种方法,迭代器是一个可以记住遍历的位置的对象

   迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束,迭代器只能往前不会后退

什么是迭代器?   满足两个条件:1 有iter方法 2 有 next 方法

我们已经知道,可以直接作用于for循环的数据类型有以下几种   一类是  list    tupie    dict   set   str   等;

一类是 generator ,包括生成器和带 yield 的generator   function,

这些都可以直接作用于for循环的对象统称为可迭代对象 Iterable 可以使用isinstance()判断一个对象是否是Iterable对象。

 

for循环内部做的三件事

1 调用可迭代对象的iter方法返回一个可迭代对象

2 不断调用迭代器对象的next方法

3处理stoplteration

 

 

l = [1,2,3,4,5,]

d = iter(l)

print(d)
#什么是迭代器?
#满足两个条件:1 有iter方法  2 有 next 方法

print(next(d))
print(next(d))
print(next(d))
print(next(d))

print(next(d))

  

判断

 Iterable 可以使用isinstance()判断一个对象是否是Iterable对象

 

from collections import Iterator

ret1 = isinstance([],Iterator)
print(ret1)

ret2 = isinstance('abc',Iterator)
print(ret2)

ret3 = isinstance((x for x in range(10)),Iterator)
print(ret3)

ret4 = isinstance(8888,Iterator)
print(ret4)

  

 

posted @ 2018-08-19 17:53  取经之路  阅读(125)  评论(0)    收藏  举报