Python学习笔记(函数篇下)

3.装饰器

3.1 闭包

如果在一个内部函数里,对外层作用域的变量进行引用(不是全局作用域),那么这个内部函数被称为闭包

闭包 = 内部函数+外部环境

作用:使垃圾回收机制不回收外部函数所占用资源,使依赖外部变量的内部函数顺利执行,实现从外部访问函数内部的变量

def outer():
    x=100

    def inner():    # inner为内部函数
        print(x)    # 调用了外部变量x

    return inner    # inner为闭包
    
outer()()	# 100

分析:outer() 返回为inner,在调用inner(),但在此步中**outer函数已经执行完成,**在执行inner中print(x)是找不到x变量的,但能返回100正确值,这种现象为闭包

3.2 装饰器

开放封闭原则:对修改封闭,对扩展开放

def decoration(func):
    def inner():
        print('Function Starts...')
        func()
        print('Function Ends...')
    return inner

@decoration # foo=decoration(foo)
def foo():
    print('foo...')

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


foo()
print('='*20)
bar()

decoration是装饰器,foo 和bar 是功能函数,decoration给功能函数扩展功能
在这里插入图片描述

装饰器帮我们做的就是将执行代码从下面框框转到上面框框

对于含有参数的装饰器:

(1)功能函数有参数

def decoration(func):
    def inner(x,y):
        print('Function Starts...')
        func(x,y)
        print('Function Ends...')
    return inner

@decoration
def add(x,y):
    print(x+y)

@decoration
def mul(x,y):
    print(x*y)

add(2,3)
mul(2,3)

在inner 和 func 中要同步参数

(2)装饰器函数有参数

def logger(flag='Ture'):
    def decoration(func):
        def inner(x,y):
            print('Function Starts...')
            func(x,y)
            print('Function Ends...')
            if flag=='Ture':
                print('已记录日志')
        return inner
    return decoration

@logger()   # @logger() -> @decoration,作用为传递了一个参数flag
def add(x,y):
    print(x+y)

@logger('a')
def mul(x,y):
    print(x*y)

add(2,3)
print('='*20)
mul(2,3)

在原本装饰器函数外在加一个带参数函数,使原来装饰器函数成为闭包。logger()执行返回decoration, @logger() -> @decoration ,区别就是传递了一个flag函数

4.生成器和迭代器

4.1 列表生成器
def f(x):
    return x**2

list1=[f(x) for x in range(1,11)]
list2=[x**2 for x in range(1,11)]
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
4.2 生成器

优点:节省内存,用的时候拿出

(1) (x*2 for x in range(1,6))生成

a = (x*2 for x in range(1,6))
print(a)    #<generator object <genexpr> at 0x000001FA8C17FC10>

# print(a.__next__()) # 在Py2中 a.next()
# print(next(a))  # 2
# print(next(a))  # 4
# print(next(a))  # 6
# print(next(a))  # 8
# print(next(a))  # 10
# 生成器为可迭代对象
for i in a:
    print(i)

(2)yield 生成生成器

def foo():
    print('First')
    yield 1
    print('Second')
    yield 2
    print('Third')
    yield 3

print(foo)	#<function foo at 0x00000208561BA940>
print(foo())	# <generator object foo at 0x00000208561BFC10>
a = foo()
for i in a:
    print(i)

总结yield:只能在函数内使用

1.yield提供了一种自定义迭代器的解决方案

2.yield可以保存函数的暂停的状态

3.yield对比return:相同点,都可以返回值,值得类型与个数没有限制,不同点:yield可以返回多次值,而return只能返回一次值函数就会结束
(3) send() 给函数里传值

def foo():
    print('First')
    yield 1
    print('Second')
    count =yield 2
    print(count)
    print('Third')
    yield 3
a = foo()
print(a.send(None))	#First 1
print(a.send(2))    #给yield 1  结果:Second 2
print(a.send(3))    #给yield 2,也就是count 结果:3 Third 3
4.3 迭代器

迭代器:

1既内置有__next__方法的对象,执行该方法可以不依赖索引取值

2.又内置有iter方法的对象,执行迭代器的__iter__方法得到的依然是迭代器本身

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

list1 = [1,2,3]
# print(list1.__iter__()) 
print(iter(list1))  #<list_iterator object at 0x00000284839B8A60> 用内置方法iter()来替代__iter__()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值