闭包函数和装饰器

闭包函数

什么是闭包函数

闭包即函数内部函数对外部作用域而非全局作用域的引用,说白了就是将函数内部的变量拿到全局来使用,还不会修改局部变量的值

def outter():
    x = 5
    def inner():
        return x
    return inner

f = outter()

x = f() + 1
print(f())
print(x)
5
6

两种为函数传参的方式

  1. 使用参数的形式
def f1(x):
    print(x)
    
f1(1)
f1(2)
f1(5)
1
2
5
  1. 包给函数
def outter(x):
    def inner():
        print(x)
    return inner

f = outter(1)
f()

f1 = outter(5)
f1()

f()
f1()
1
5
1
5

装饰器

无参装饰器

什么是装饰器

装饰器就是为函数添加额外的功能

注意:

  • 装饰器本身其实是可以任意可调用的对象
  • 被装饰的对象也可以是任意可调用的对象

装饰器的两大原则

  1. 不修改被装饰对象的源代码
  2. 不修改被装饰对象的调用方式

装饰器其实就是遵循以上两大原则的前提下为被装饰对象添加功能

怎样用装饰器

如果我们定义一个函数,需要增加一个计时功能,我们可以使用改变源代码的方式:

import time

def index():
    start_time = time.time()
    print('睡一秒')
    time.sleep(1)
    end_time = time.time()
    print(end_time - start_time)
    
index()
睡一秒
1.0007741451263428

但这样就不符合我们装饰器的两大原则了,那我们该怎么来实现呢?

第一种:改变调用方式

import time

def outer(func):
    
    start_time = time.time()
    res = func()
    end_time = time.time()
    print(end_time - start_time)


def index():
    print('睡一秒')
    time.sleep(1)
    
outer(index)
睡一秒
1.0006616115570068

第二种:包给函数-外包

import time

def outer(func):
    def wrapper():
        start_time = time.time()
        res = func()
        end_time = time.time()
        print(end_time - start_time)
    return wrapper


def index():
    print('睡一秒')
    time.sleep(1)
    
index = outer(index)
index()
睡一秒
1.0004618167877197

完善装饰器

上述的装饰器,最后调用index()的时候,其实是在调用wrapper(),因此如果原始的index()有返回值的时候,wrapper()函数的返回值应该和index()的返回值一样,所以我们需要同步原始的index()和wrapper()方法返回值。

import time

def outer(func):
    def wrapper():
        start_time = time.time()
        res = func()
        end_time = time.time()
        print(end_time - start_time)
        return res
    return wrapper


def index():
    print('睡一秒')
    time.sleep(1)
    return  '我有返回值'
    
index = outer(index)
res = index()
print(res)
睡一秒
1.000257968902588
我有返回值

如果原始的index()方法需要传参,那么我们之前的装饰器是无法实现该功能的,由于有wrapper()=index(),所以给wrapper()方法传参即可

import time

def outer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        end_time = time.time()
        print(end_time - start_time)
        return res
    return wrapper


def index(x):
    print('睡一秒')
    time.sleep(1)
    return  f"传入值为:{x}"
    
index = outer(index)
res = index(5)
print(res)
睡一秒
1.0001804828643799
传入值为:5

装饰器语法糖

import time

def outer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        end_time = time.time()
        print(end_time - start_time)
        return res
    return wrapper

@outer   # index = outer(index)
def index(x):
    print('睡一秒')
    time.sleep(1)
    return  f"传入值为:{x}"
    
res = index(5)
print(res)
睡一秒
1.0002069473266602
传入值为:5

装饰器模板

def deco(func):
    def wrapper(*args,**kwargs):
        res = func(*args,**kwargs)
        return res
    return wrapper

@deco
def f1():
    pass
原文地址:https://www.cnblogs.com/Hades123/p/10997882.html