Python 装饰器、生成器、迭代器

装饰器

作用:为其他函数增加功能

装饰器必须要明白以下几点:

1.作用域

2.高阶函数

3.闭包

 

from functools import reduce
import time


def outside(func):
    def inside(*args):
        start = time.time()
        func(*args)
        end = time.time()
        result = end - start
        print(result)
    return inside

@outside #同于 add = outside(add)
def add(*args):
    num = reduce(lambda a,b : a+b, args)
    time.sleep(0.2)
    print(num)

@outside
def mul(*args):
    num = reduce(lambda a,b : a*b, args)
    time.sleep(0.4)
    print(num)


if __name__ == "__main__":
    add(*range(1,101))
    mul(*range(1,6,2))

 

生成器

什么是生成器:

 

生成器本身是没值的,只有你调用了,才会给你返回值。

列表就好比是,厨师把所有的菜全部端上桌子,你想吃那个你点那个,不过有占地方

生成器就好比是,厨师还没做,当你点完所有想吃的菜之后,厨师先只给你做一个,只有你把前面的菜吃完了,才能给你继续做下一个。

 

创建生成器:

 

1、(x for x in range(10))

num = (x**2 for x in range(1,11))

2、yeild

def func():
    print("first")
    yield 1
    print("second")
    yield 2
# 此时的func函数就是一个生成器对象

 

查看生成器的值:

1、next()  等同于 __next__()

num = (x**2 for x in range(1,11))
print(next(num))
print(next(num))

2、for循环

def func():
    print("first")
    yield 1
    print("second")
    yield 2

for i in func():
    print(i)

为什么使用for 就不用再使用next 了呢?
因为for循环内部有一个next(),所以在for循环中不需在调用next()

 3、send

send方法与,next方法类似。,用于yield的前的变量。

send方法可以为变量传值,前提是必须要有变量。

如果生成器还没进入,但还要使用send 方法,参数必须是None。

def func():
    print("first")
    parameter = yield 1
    print(parameter)
    yield 2
    yield "third"

f = func() # f是生成器对象

f.send(None)
f.send("second")
print(next(f))

 

迭代器

生成器都是迭代器,但迭代器不一定是生成器。

 

什么是可迭代对象(iterable):

能被iter方法调用,例:列表,元祖,字典,集合,字符串

 

什么是迭代器(iterator):

能被iter方法,next方法调用。

 

for循环内部所做的事情:

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

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

3.处理StopIteration

 

# 创建迭代器对象
number = [1,2,3]
print(type(number)) # <class 'list'>

number = iter(number) # 等同 __iter__()

print(type(number)) # <class 'list_iterator'>

# 调用
next(number)
for i in number:
    print(i)

 

posted @ 2019-06-23 21:53  Sun先生  Views(367)  Comments(0Edit  收藏  举报