Python的闭包(简单闭包,装饰器,多层装饰器,装饰器工厂)

了解闭包之前我们要先知道什么是函数式编程,什么是调用函数,什么是引用函数。

# 函数式编程:把函数作为函数的参数以及返回值的变成方式

# def work1():
#     print('这是被引用的函数')
# #调用函数
# work1()


# #引用函数
# w = work1  #地址指针指向这个地址
#
# print(id(work1))
# print(id(w))



def wrapper():      #外层
    print('start')

    def inner():        #内层
        print('inner')

    print('end')
    return inner     #外层返回内层函数名

# # 1:
wrapper()       #只运行了外层

# 2:
# inner = wrapper()     #运行了外层和内层
# inner()

对调用、引用函数有了一定了解后,就可以接触闭包概念了

# 闭包是由函数及其相关的引用环境组合而成的实体
# (即:闭包=函数+引用环境)
# (想想Erlang的外层函数传入一个参数a, 内层函数依旧传入一个参数b, 内层函数使用a和b, 最后返回内层函数)

def line(a,b):

    def line_obj(x):
        nonlocal a       #   global适用于函数内部修改全局变量的值  nonlocal适用于嵌套函数中内部函数修改外部变量的值
        a += 1
        return a*x+b        #返回函数对值的操作

    return line_obj       #返回内部定义的函数名,但不运行

line1 = line(1,1)       #将line1的指针指向line的地址,这部操作实际上是引用line里定义的函数line_obj的函数名
result = line1(2)       #实质上传参并运行line_obj
print(result)

闭包的简单应用:求一个平均数

'''用闭包求平均数'''

def A(a,b):

    def B():
        nonlocal a,b
        c = (a+b)/2
        return c
    return B

a=A(1,3)
print(a())

装饰器是闭包的应用,下面是一个简单的装饰器

def one(func):
    print('1')
    def two():
        print('2')
        func()
    return two

#  @ 是装饰器的语法糖
@one   #等价于 demo = one ( demo )
def demo():
    print('3')

demo()

下面是一个简单的多层装饰器

# 装饰器避免冗余代码
def w1(func):
    def inner():
        print('w1 inner')
        func()
    return inner


def w2(func):
    def inner():
        print('w2 inner')
        func()
    return inner

#  @ 是装饰器的语法糖
# 多个装饰器的调用顺序是自下往上,但是运行时的执行顺序是自上往下!!!
@w2   # f2 = w2(f2)
@w1   # f1 = w1 (f1)
def f1():
    print('f1')


f1()

装饰器工厂就是生产装饰器的函数,下面是一个简单的装饰器工厂函数:

# 根据参数不同,生产不同的装饰器


def factory(arg=None):    #工厂函数
    def timefun(func):   #装饰器
        def inner():
            if arg:
                print('有')
            else:
                print('没')
            return func()
        return inner
    return timefun

@factory(1)     #这里的()一定要有
def f():
    print('f')

f()

猜你喜欢

转载自blog.csdn.net/sui_yi123/article/details/81937527