十二、python-闭包函数和装饰器

本文深入探讨Python编程中的闭包、装饰器、有参装饰器和迭代器的概念及应用。闭包用于封装变量,装饰器允许在不修改源代码的情况下扩展功能,遵循开放封闭原则。有参装饰器则提供了更灵活的参数配置。此外,文章还介绍了迭代器和生成器的使用,它们在处理大量数据时提供高效的方式。通过对这些概念的掌握,可以提升Python编程能力。
摘要由CSDN通过智能技术生成

一、

闭函数:封闭的意思,函数被封闭起来

包函数:函数内部包含对外层函数作用域名字的引用

实例:

def f1():
    x=10
    def f2():
        print(x)
    return f2

场景:主要就是原本的函数(f2)不能够再去给他增加新的形参的时候,而你这个函数内部恰好又需要有外部传参进来,这时候就可以用到闭包函数。

二、装饰器

定义一个函数(类或者其他的),这个函数的功能就是用来装饰其他函数的

也就是说这个函数是用来给其他函数添加额外功能的

开放封闭原则:

开放:对扩展功能(增加功能)开放,扩展功能的意思是在源代码不做任何改变的情况下,为其增加功能。

封闭:对修改源代码是封闭的

def inside(group,s,z):
    print(group)
    print(s)
    print(z)

def recharge(num):
    for i in range(num,100):
        time.sleep(0.05)
        print(i)
    print('充满')
    return 100

#下面的函数就是装饰器示例
"""
此时如果上面两个函数的参数发生了变化,并且已经修改的函数,但是如果调用的时候使用了
装饰器来调用,在函数修改后,调用函数的地方就可以不用修改了,
"""
def outer(func):
    def wrapper(*args,**kwargs):
        start = time.time()
        respense = func(*args,**kwargs)
        end = time.time()
        print(end-start)
        return respense

"""
通过下面的两行代码,能够将内存地址直接指向原函数,而不是wrapper函数,
并且函数注释也是指向了原函数。
"""
        wrapper.__name__ = func.__name__
        wrapper.__doc__ = func.__doc__
    return wrapper


"""
语法糖
就是在定义函数的时候直接声明调用装饰器函数,就会将装饰后的函数地址后返回
并赋值给原来的函数变量
"""
@outer    #此处就相当于funcc = outer(funcc)
def funcc(a,b,c)
    pause

为了能够将内存地址直接指向原函数,而不是wrapper函数,并且函数注释也是指向了原函数除了使用上面直接赋值的方法,还可以导入一个装饰器在完成。

导入wraps

from functool import wraps

from functool import wraps


#下面的函数就是装饰器示例
"""
此时如果上面两个函数的参数发生了变化,并且已经修改的函数,但是如果调用的时候使用了
装饰器来调用,在函数修改后,调用函数的地方就可以不用修改了,
"""
def outer(func):
    @wraps(func)
#有了上面这行代码,下面的wrapper.__name__,wrapper.__doc__赋值代码就可以去掉了。
    def wrapper(*args,**kwargs):
        start = time.time()
        respense = func(*args,**kwargs)
        end = time.time()
        print(end-start)
        return respense

"""
通过下面的两行代码,能够将内存地址直接指向原函数,而不是wrapper函数,
并且函数注释也是指向了原函数。
"""
        wrapper.__name__ = func.__name__
        wrapper.__doc__ = func.__doc__
    return wrapper

三、有参装饰器

语法糖限制了装饰器只能有一个参数。

应用样例:

def auth(source):
    def outer(func):
        def wrapper(*args,**kwargs):
            name = input("输入账号").strip()
            pwd = input("输入密码").strip()
            if source == 'file':
                ptint('基于文件')
                if name == 'jack' and pwd == '123':
                    res = func(*args,**kwargs)
                    return res
                else:
                    print('错误')
            elif source == 'sql':
                print('基于sql')
            else:
                print('不支持')
        return wrapper
    return outer

@auth('file')
def home():
    print('welcome')

@auth('sql')
def index():
    pass

四、装饰器叠加使用

#装饰器的叠加使用
@outer3    #home = =outer3(home)   #outer3.wrapper
@outer2    #home = =outer2(home)   #outer2.wrapper
@outer1    #home = =outer1(home)   #outer1.wrapper
def home():
    pass
"""
装饰器的调用顺序是:outer1->outer2->outer3
"""

五、迭代器

可迭代对象:

只要内置有__iter__()方法的就可以称之为可迭代对象。可以转换为迭代器的对象

dict = {key1:'value1',key2:'value2',key3:'value3'}
res = dict.__iter__()
while True:
    try:
        print(res.__next__())
    except StopIteration:       #用来捕获异常
        break
  如果想再次取值,就必须重新调用一次:res = dict.__iter__(),否则就会直接抛出异常

迭代器对象:内置有__next__()方法,并且还内置有__iter__()方法的对象。

迭代器对象调用__next__()方法,就会得到迭代器的下一个值,迭代器对象调用__iter__()方法,得到的是迭代器本身。

六、生成器

生成器就是迭代器,

def func():

        print('第一次执行')

        yield 1

        print(‘第二次执行’)

        yield 2

        print('第三次执行')

        yeild 3

#上面函数虽然没有return,但是会返回一个生成器,可以使用__next_来取值。

yield表达式:

yield会将函数暂停到当前位置,并返回yield后面的值。

yield可以接收send()过来的值,并赋值给一个变量,比如:g.send(10)。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值