python:高级(二)

2019-02-23  本文已影响11人  alan2yang

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


一、闭包

闭包三要素:

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

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

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

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

  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()
上一篇 下一篇

猜你喜欢

热点阅读