闭包函数和装饰器

闭包函数

闭包函数的两大特征

  1. 闭:定义在函数内部的函数
  2. 包:内部函数使用了外层函数名称空间中的名字
def outer():
    name = 'trump'

    def inner ():
        print("from inner function,", f'my name is {name}.')

    return inner 


name = 'obama'
res = outer()
res()
图片名称

闭包函数实际应用

# 闭包函数是给函数体传参的另外一种方式,第一种用形参
def outer(username):
    def index():
        if username.isupper():
            print(username)
        else:
            cap_name = username.upper()
            print(cap_name)
    return index


res = outer('trump')
res()

装饰器

  • 装饰器的本质
    在不改变被装饰对象原有的'调用方式'和'内部代码'的情况下给被装饰对象添加新的功能

  • 装饰器的原则

  1. 对扩展开放
  2. 对修改封闭
  • 应用
# 实际应用:统计函数的执行时间
import time


def index():
    time.sleep(2.5)
    print('from index')


start_time = time.time()  # 函数执行之前获取一个时间戳
index()
end_time = time.time()  # 函数执行之后获取一个时间戳
print(end_time - start_time)  # 两个时间戳的差值就是函数的执行时间
图片名称

简易版本装饰器

# 能够做到调用方式一致
import time


def delete():
    time.sleep(1.5)
    print('running delete')


print(delete)


def outer(func):
    def get_time():
        start_time = time.time()  # 函数执行之前获取一个时间戳
        func()  # 执行被装饰的的delete函数
        end_time = time.time()  # 函数执行之后获取一个时间戳
        print(end_time - start_time)  # 两个时间戳的差值就是函数的执行时间

    return get_time


delete = outer(delete)  # 右边是一个普通变量名
delete()  # running delete 1.5109477043151855
print(delete)  # <function outer.<locals>.get_time at 0x0000020E388BE378>
图片名称

进阶版本装饰器

# 解决的是参数问题
import time
def func_name(a):
    time.sleep(2)
    print(f'running {a} func')

def outer(func_name):
    def get_time(*args, **kwargs):
        start_time = time.time()
        func_name(*args, **kwargs)
        end_time = time.time()
        print(end_time - start_time)

    return get_time


res = outer(func_name)
res('delete')

完整版本装饰器

# 解决的是返回值问题
import time


def func_name(a):
    time.sleep(1)
    print(f'ruing {a} func')


def outer(func_name):
    def get_time(*args, **kwargs):
        start_time = time.time()
        res = func_name(*args, **kwargs)  # 执行被装饰的函数
        end_time = time.time()
        print(end_time - start_time)
        return res

    return get_time
func_name = outer(func_name)
func_name('modify')
图片名称

装饰器模板

def func_mame():
    print('from func')
    return
def outer(func_name):
    def inner(*args, **kwargs):
        print('程序执行之前,可以添加的操作')
        res = func_name(*args, **kwargs)
        print('程序执行之后,可以添加的操作')
        return res
    return inner
func_name = outer(func_mame)
func_mame()

装饰器语法糖

def outer(func_name):
    def inner(*args, **kwargs):
        print('程序执行之前,可以添加的操作')
        res = func_name(*args, **kwargs)
        print('程序执行之后,可以添加的操作')
        return res

    return inner


@outer
def func_mame():
    print('from func')
    return


func_mame()

装饰器修复技术

from functools import wraps
def outer(func_name):
    @wraps(func_name)
    def inner(*args, **kwargs):
        print('程序执行之前,可以添加的操作')
        res = func_name(*args, **kwargs)
        print('程序执行之后,可以添加的操作')
        return res

    return inner


@outer
def func_mame():
    """func用法"""
    print('from func')
    return


func_mame()
help(func_mame)
图片名称
posted @ 2022-03-18 23:00  一梦便是数千载  阅读(23)  评论(0编辑  收藏  举报