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

一、生成器

只有当需要使用值时,才生成数据,避免了没有内存储存庞大的数据问题。

1、创建生成器

①创建生成器方法1

#1、把列表生成器的中括号编程小括号

a = [x for x in range(10)]
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

b = (x for x in range(10))
#b为生成器

#输出b
for i in range(10):
    next(b)

②创建生成器方法2

#生成斐波那契数列方法

def creatNum():
    a, b = 0, 1
    for i in range(5):
        yield b
        a, b = b, a+b

num = creatNum() #生成器

#next(num)
#num.__next__()
#以上两种方式是一样的

for n in num:
    print(n)

#num 这个生成器执行,如果是第一次执行,则从creatNum开始执行;否则,从上次停止的地方执行。
#每次函数执行都会在yield处停止,并返回一个值

2、send

def test():
    for i in range(5):
        temp = yield(i)
        print(temp)

t = test()

print(next(t))
print(next(t))

# 0
# None
# 1

print(t.send('haha'))

# haha
#2

# yield 没有返回值 None
# send 给yield传递信息,从yiel停止处执行,故不能直接第一次就执行send
# 若非要第一次就执行 send ,则可 t.send(None)

二、迭代器

1、可迭代对象:Iterable

①集合类型数据:list、tuple、dict、set、str等

②generator,包括生成器和带 yield 的 generator function

如何判断一个对象是否可迭代:

from collections import Iterable

#用 isinstance 判断

isinstance([], Iterable) #True

#True表示可以迭代,False表示不可迭代

2、迭代器

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

from collections import Iterator

#用 isinstance 判断

isinstance([], Iterator) #False

#True表示可以迭代,False表示不可迭代

3、iter()函数

生成器都是Iterator对象,但list、dict、str虽然可以iterable但那不是iterator,用iter函数可以使他们变成迭代器

isinstance(iter([]), Iterator) #True

三、闭包

1、函数引用

def test():
    for i in range(5):
        print("-------1-----")

b = test # b 为函数引用

2、闭包

在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的变量称为闭包

def test(number):
    print("-------1-------")
    
    def test_in():
        print("-------2-------")
        print(number+100)

     print("-------3-------")
    return test_in

t = test(100)
print("---------------------")
t()

# 输出为:
# -------1-------
# -------3-------
# ---------------------
# -------2-------
# 200

闭包的实例

#创建直线方程
def line_conf(a, b):

    def line(x):
        return a*x + b

    return line

line1 = line_conf(1, 1)
line2 = line_conf(4, 5)

print(line(5))
print(line(5))

四、装饰器

在不改变原有函数功能的情况下,对函数进行扩展。

def w1(func):
    def inner():
        print("----正在验证权限----")  #扩展部分
        func()
    return inner

def f1():
    print("-----f1-----")

def f2():
    print("-----f2-----")

#在不改变 原f1 函数的基础上,对 f1 进行功能上的扩展
f1 = w1(f1)
f1()
def w1(func):
    def inner():
        #验证1
        #验证2
        #验证3
        func()
    return inner

@w1
def f1():
    print("f1")

@w1
def f2():
    print("f2")

@w1
def f3():
    print("f3")

@w1
def f4():
    print("f4")

 装饰器什么时候开始起作用:

def w1(func):
    print("----正在装饰中-----")
    def inner():
        print("----正在验证权限----")  #扩展部分
        func()
    return inner


#只要python解释器执行到了这行代码,那么就会自动进行装饰,而不是等到调用的时候才进行装饰
@w1
def f1():
    print("-----f1-----")

#在调用f1之前,已经进行了装饰
f1()

# @w1 就相当于 f1 = w1(f1)

1、装饰器对有参数、无参数函数进行装饰

对无参数的函数进行装饰

def func(funcName):
    print("--func-1----")
    def func_in():
        print("---func_in-1--")
        funcName()
        print("---func_in-2--")
    print("--func-2----")
    return func_in

@func
def test():
    print("----test-----")

test()

对有参数的函数进行装饰

#对定长参数函数进行装饰

def func(funcName):
    print("--func-1----")
    def func_in(a, b):
        print("---func_in-1--")
        funcName(a, b)
        print("---func_in-2--")
    print("--func-2----")
    return func_in

@func
def test(a, b):
    print("----test-----")

test(11, 22)


#对不定长参数函数进行装饰

def func(funcName):
    print("--func-1----")
    def func_in(*args, **kwargs):
        print("---func_in-1--")
        funcName(*args, **kwargs)
        print("---func_in-2--")
    print("--func-2----")
    return func_in

@func
def test1(a, b):
    print("a=%d,b=%d"%(a,b))

@func
def test2(a, b, c):
    print("a=%d,b=%d,c=%d"%(a,b,c))

test1(11, 22)
test2(11, 22, 33)

2、对带有返回值的函数进行装饰

#对定长参数函数进行装饰

def func(funcName):
    print("--func-1----")
    def func_in():
        print("---func_in-1--")
        ret = funcName() #保存返回的"haha"
        print("---func_in-2--")
        return ret
    print("--func-2----")
    return func_in

@func
def test(a, b):
    print("----test-----")
    return "haha"

ret = test()
print("test return value is %s"%ret)

3、通用装饰器

def func(funcName):
    
    def func_in(*args, **kwargs):
        ret = funcName(*args, **kwargs)
        return ret

    return func_in

@func
def test1():
    print("----test1----")
    return "haha"

@func
def test2():
    print("----test2----")

@func
def test3(a):
    print("----test3----a=%d"%a)

ret = test1()
print("test1 return value is %s"%ret)

test2()

test3(11)

4、带有参数的装饰器

装饰器带参数,在原有装饰器的基础上,设置外部变量

def func_arg(arg):
    def func(funcName):
        def func_in():
            print("-----args=%s----"%arg)            
            funcName()
        return func_in
    return func

# 1、先执行func_arg("heihei")函数,这个函数return的结果是func这个函数的引用
# 2、@func
# 3、使用 @func 对函数test进行装饰

@func_arg("heihei")
def test1():
    print("----test1----")

@func_arg("haha")
def test2():
    print("----test2----")

#带有参数的装饰器,能够在运行时,有不同的功能
test1()
test1()

5、类当装饰器

class Test(object):
    def __init__(self, func):
        print("----初始化----")
        print("func name is %s"%func.__name__)
        self.__func = func

    def __call__(self):
        print("----装饰器中的功能----")
        self.__func()

# @Test 等同于  test = Test(test)
@Test
def test():
    print("----test----")

#装饰器 @Test 处执行__init__
#----初始化----
#func name is test

test() #执行 __call__
#----装饰器中的功能----
#----test----

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值