欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python装饰器与闭包

程序员文章站 2022-07-12 10:01:20
...

python装饰器与闭包

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

def outer(x):
    def inner():
        print(x+9)
    return inner

inner = outer(10)
inner()

正常情况下,L-E-G-B原则,inner()作为内部函数,处于L级别local应无法调用上一层级的变量(作用域不同),在满足闭包的情况下,可以直接调用;

装饰器的开放封闭原则:对扩展开放,对修改封闭!!!
源代码为:

def foo():
    x = 0
    for i in range(10000000):
        x += 1
    print(x)
foo()

此时需要将源代码扩展,增加计算此函数运行所需时间,不考虑装饰器的情况下:

import time
def foo():
    startTime = time.time()
    x = 0
    for i in range(10000000):
        x += 1
    print(x)
    endTime = time.time()
    print("useTime:%s"%(endTime-startTime))
foo()

或:

import time
def foo():

    x = 0
    for i in range(10000000):
        x += 1
    print(x)


def show_time(f):
    startTime = time.time()
    f()
    endTime = time.time()
    print("useTime:%s" % (endTime - startTime))

show_time(foo)

在各大公司,当一个函数被大量调用后,无法得知,此函数是否被其他人员调用,因此,对于已经实现的函数功能,不可对源码进行更改,即“开放封闭原则“,故需要使用到装饰器:

import time
def foo():
    x = 0
    for i in range(10000000):
        x += 1
    print(x)

def show_time(f):
    def inner():
        startTime = time.time()
        f()
        endTime = time.time()
        print("useTime:%s" % (endTime - startTime))
    return inner

foo = show_time(foo)
foo()

使用闭包,内部函数调用外部变量,再将函数赋值,按原函数调用时,就会执行闭包中的内部函数,以此调用原函数,达到不改变原函数与调用方式,做到扩展原来功能的要求。
python默认将foo = show_time(foo)代码使用@表示:

import time

def show_time(f):
    def inner():
        startTime = time.time()
        f()
        endTime = time.time()
        print("useTime:%s" % (endTime - startTime))
    return inner

@show_time    #foo = show_time(foo)
def foo():
    x = 0
    for i in range(10000000):
        x += 1
    print(x)

foo()

装饰器的作用即为,在引用函数时,将原调用函数执行红色部分变动为执行蓝色部分
python装饰器与闭包

相关标签: python