美文网首页
python:高级(二)

python:高级(二)

作者: alan2yang | 来源:发表于2019-02-23 13:53 被阅读11次

    自己以前整理的笔记,不太完整,后续会不断更新。。。。


    一、闭包

    闭包三要素:

    • 函数嵌套
    • 内层函数对外层函数参数的调用
    • 外层函数返回内层函数的引用

    外层函数可以实现保存其实参数据的功能,以供内层函数使用

    返回的内层函数空间中保存着外层函数的所有数据,可以调用

    一般用于简单功能的实现,更复杂的功能用函数实现

    思考:函数、匿名函数、闭包、对象 当做实参时 有什么区别?

    1. 匿名函数能够完成基本的简单功能,,,传递是这个函数的引用 只有功能
    2. 普通函数能够完成较为复杂的功能,,,传递是这个函数的引用 只有功能
    3. 闭包能够完成较为复杂的功能,,,传递是这个闭包中的函数以及数据,因此传递是功能+数据
    4. 对象能够完成最为复杂的功能,,,传递是很多数据+很多功能,因此传递是功能+数据

    在内层函数中修改外层函数的数据,需要使用nonlocal关键字声明之后,才能修改

    并且声明nonlocal后可以实现:类中类属性的作用,能够记录每一次调用内部函数的情况

    二、装饰器

    需求:在不修改原有代码的前提下,扩展现有功能

    效果:类似于类中继承后方法的重写,给父类的方法在原有功能的基础上新增功能

    装饰器建立在闭包的基础上,调用被装饰函数时,本质上是调用内层函数,包括传参也通过内层函数实现

    所谓实现“重写”的功能,也就是通过内层函数实现的

    执行到装饰器时,过程如下:

    • 将原函数作为实参传入到装饰器函数中,并将返回值赋值给原函数变量名,即指向装饰器内部函数
    • 当再次调用原函数时,实际上调用的是装饰器内部函数

    即当解释器执行到装饰器时,自动执行装饰器函数,那么我们只要在装饰器函数中添加功能,就可实现自动操作

    # 装饰器原理解析
    def outer(fun):
        def inner():
            print('add function')
            fun()
        return inner
    
    # outer装饰器
    @outer   # 解释到这里时自动实现:test= outer(test)
    def test():
        print('hello')
    
    # 所以这里的test不再是原函数test,而是一个新的test指向inner,同名覆盖
    # 这里调用时相当于调用inner()
    test()
    # 结果:
    # add function
    # hello
    
    # 装饰器原理分析---自动执行验证
    
    def outer(fun):
        # 在自动执行的步骤中添加功能,可实现自动功能
        print('-----')
    
        def inner():
            print('add function')
            fun()
        return inner
    
    
    # python解释器执行到装饰器时,自动执行一步test= outer(test)
    @outer
    def test():
        print('hello')
    
    # 即使这里不调用函数,依然会执行一步
    # 结果:
    # -----
    

    多个装饰器

    多个装饰器装饰一个函数:从下向上装饰

    # 装饰器原理分析---多个装饰器
    
    def outer_h(fun):
        def inner():
            print('---add h---start')
            return '<h1>'+fun()+'</h1>'
        return inner
    
    
    def outer_b(fun):
        def inner():
            print('---add b---start')
            return '<b>'+fun()+'</b>'
        return inner
    
    
    # python解释器执行到多个装饰器时,会先执行最底部的装饰器,即先完成一个装饰器获得一个返回的函数inner()
    # 再依次向上完成其他装饰器,将返回的函数作为一个新的被装饰函数
    
    @outer_h
    @outer_b
    def test():
        return 'hello world!'
    
    print(test())
    # 结果:
    # ---add h---start
    # ---add b---start
    # <h1><b>hello world!</b></h1>
    

    通用装饰器

    1.内部函数传参args,*kwargs

    2.内部函数有返回值

    # 通用装饰器
    
    def outter(fun):
        def inner(*args, **kwargs):  # 起到中转的作用
            print('do something')
            return fun(*args, **kwargs)  # --->接收原函数test(a,b,c)的参数
        return inner
    
    
    @outter
    def test(a,b,c):
        print(a+b+c)
    
    test(1,2,3)
    

    带有参数的装饰器

    严格遵循装饰器在不修改原代码的前提下,实现同一个装饰器对不同原函数添加不同功能的目的

    # *-* coding:utf-8 *-*
    # 带参数的装饰器
    
    def shell(temp):
        def outter(func):
            def inner(*args, **kwargs):
                # add something
                if temp == 'index':
                    print('authorise level 1')
                elif temp == 'center':
                    print('authorise level 2')
                return func(*args, **kwargs)
            return inner
        return outter
    
    
    @shell('index')  # 效果:先执行shell()函数,返回outter()函数,再用outter装饰原函数
    def index():
        print('this is index')
    
    
    @shell('center')
    def center():
        print('this is center')
    
    
    index()
    center()
    # 结果:
    # authorise level 1
    # this is index
    # authorise level 2
    # this is center
    

    类装饰器

    # 类装饰器的原理与函数类似
    
    
    class Test(object):
        def __init__(self,func):
            self.func=func
    
        def __call__(self, *args, **kwargs):
            print('add something')
            return self.func()
    
    
    @Test  # 实现类似于test=Test(test)的功能
    def test():
        print('this is a test')
    
    
    # 当在实例对象后面加()时,默认调用类中的__call__方法
    test()
    

    相关文章

      网友评论

          本文标题:python:高级(二)

          本文链接:https://www.haomeiwen.com/subject/biqpyqtx.html