python--闭包和装饰器

闭包和装饰器

闭包

  • 两个函数的嵌套,外部函数返回内部函数的引用,并且外部函数都有参数
# 闭包的写法,两层函数的嵌套,外部函数返回内部函数的引用,外层函数都带参数
 def 外层函数的名称(参数):
     def 内层函数的名称():
         pass
     return  内层函数的引用
  • 函数以及闭包之间的区别
    • lambda就是完成一段简单的功能
    • 函数就是完成一段功能
    • 对象是多个函数跟数据的合集
    • 闭包是完成一段功能时需要一个保持一个数据

nonlocal

  • 功能和global功能相似,
  • global指定被修饰的变量为全局
  • nonlocal指定被修饰的变量不是局部
def set_fun(func):
    func = 254
    def call_fun():
        nonlocal func  # 修改外层函数的值,并且内部函数有外部函数相同的变量名
        print(func)
        func = 100
    return call_fun

fun = set_fun(123)
fun()

装饰器

  1. 创建一个闭包(终级版)
  2. @xx装饰你要装饰的函数

万能装饰器

def set_fun(func):
    def call_fun(*args,**kwargs):
        return func(*args,**kwargs)
    return call_fun

@set_fun
def test():
    pass
  • 装饰器在不改变原先的函数代码的情况下,给原先的函数添加额外的功能(原则)
  • 装饰器不会去改变原函数的参数及结果
  • 装饰前的函数(test),是由func指向的
  • 装饰后的函数(test),是指向了call_fun

案例

# 定义函数:完成包裹数据
def makeBold(fn):
    def wrapped():
        return "<b>" + fn() + "</b>"
    return wrapped

# 定义函数:完成包裹数据
def makeItalic(fn):
    def wrapped():
        return "<i>" + fn() + "</i>"
    return wrapped

@makeBold
def test1():
    return "hello world-1"

@makeItalic
def test2():
    return "hello world-2"

@makeBold
@makeItalic
def test3():
    return "hello world-3"

print(test1())
print(test2())
print(test3())

运行结果:

<b>hello world-1</b>
<i>hello world-2</i>
<b><i>hello world-3</i></b>

装饰器功能

  1. 引入日志
  2. 函数执行时间统计
  3. 执行函数前预备处理
  4. 执行函数后清理功能
  5. 权限校验等场景
  6. 缓存

案例

# 作业要求
# 设计装饰器
# 计算某函数的执行次数,用户行为分析
# 计算某函数的执行时间,优化

import random
import time

# 定义装饰器1,计算次数
def out_fun1(func):
    count = 0

    def inner_func():
        func()
        nonlocal count
        # global count
        count += 1
        return count
    return inner_func


# 定义装饰器2,计算时间
def out_fun2(func):
    def inner_func():
        start = time.time()
        func()
        end = time.time()
        return end - start
    return inner_func


@out_fun1
def demo():
    a = 0
    for x in range(1, 100001):
        a += x
    # print('计算100000以内的累加,结果为:', a)


@out_fun1
def demo1():
    a = 1
    for x in range(1,101):
        a *= x
    # print('计算1-100累积,结果为:', a)


@out_fun2
def test():
    for x in range(100):
        index = random.randint(90, 100)
        if index % 2 == 0:
            count = demo()
            print('第', count, '次执行Demo函数')
        else:
            count = demo1()
            print('Demo1函数,第', count, '次执行')


print('共用时', test())

猜你喜欢

转载自blog.csdn.net/lb786984530/article/details/81193141