day 12

1. 闭包函数

闭包函数:将 闭包函数内部的变量 与 闭包函数内部的函数 打包在一块儿,以函数返回值的形式返回出来闭包

def f1():
    def f2():
        print('from f2')
    return f2   # 将 函数 f2 的对象做为函数 f1 的返回值
f2 = f1()   # 当调用函数 f1 的时候,实际上在调用函数 f2 ,
f2()

因为局部做用域与全局做用域下相同名字的变量是没有任何关系的,因此在正常状况下,咱们是不能直接在外部调用 函数 f2 ,实现打印功能的,运用闭包的思想,能够实现这种需求。app

2. 装饰器

装饰器:给函数增长功能的函数函数

  • 装饰器自己也是一个函数,只是被用来装饰被装饰的函数
  • 使用装饰器函数时,不改变被装饰函数的源代码
  • 使用装饰器函数时,不改变被装饰函数的调用方式

2.1 装饰器模板

# 装饰器模板
def deco(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        return res

    return wrapper

2.2 装饰器语法糖

当一个函数具备装饰器时时可使用装饰器语法进行快捷方便的调用code

# 在被装饰函数正上方,而且是单独一行写上:@装饰器名
@deco
def f1():
    pass

2.3 三层装饰器

给二层装饰器函数传参。对象

# 三层装饰器
def sanceng(func3)
    def deco(func):
        def wrapper(*args, **kwargs):
            res = func(*args, **kwargs)
            return res

        return wrapper
    return deco

2.4 装饰器模板推导过程

2.4.1 不带参数和返回值的装饰器

# 模板
def deco(func):
    def wrapper():
        func()    
    return wrapper

假设如今有一个函数 f1作用域

import time
def f1():   # 函数对象 f1
    print('from f1')    # 函数功能
    time.sleep(1)
    
f1()    # 调用方式

如何在不改变函数的源代码及调用方式的前提下,实现计算 f1 功能耗费的时间it

实现方法以下:模板

import time
def f1():   # 函数对象 f1
    '''被装饰函数'''
    print('from f1')    # 函数功能
    time.sleep(1)
    
# f1()  # 调用方式

def deco(func): # 2. 这里的 func 其实是真正的 f1 函数对象
    '''装饰器'''
    def wrapper():  # 3. 添加须要实现的功能
        start = time.time()
        func()      # 4. 至关于 f1(),调用函数 f1
        end = time.time()
        print(end - start)
    return wrapper  # 5. 将实现功能的函数对象 wrapper 和 结果 打包返回给装饰器函数 deco
f1 = deco(f1)   # 1. 将函数对象 f1 看成参数传给装饰器函数,会的到一个返回值对象使用 f1 接收,这里的 f1只是个普通的变量名,可是接收了函数对象 wrapper
f1() # 6. 实现了 f1 原来的功能,同时获得了运行程序的时间(这里的其实是在调用装饰器函数里面的 wrapper ,已经不是原来的函数 f1 了)

2.4.2 带返回值的装饰器

# 模板
def deco(func):
    def wrapper():
        res = func()    
    return wrapper

假设如今有一个函数 f1class

import time
def f1():   # 函数对象 f1
    print('from f1')    # 函数功能
    time.sleep(1)
    return '返回值'
    
# f1()  # 调用方式

在不改变函数的源代码及调用方式的前提下,实现计算 f1 功能耗费的时间

实现方法以下:

import time
def f1():   # 函数对象 f1
    '''被装饰函数'''
    print('from f1')    # 函数功能
    time.sleep(1)
    return '返回值'
    
# f1()  # 调用方式

def deco(func): # 2. 这里的 func 其实是真正的 f1 函数对象
    '''装饰器'''
    def wrapper():  # 3. 添加须要实现的功能
        start = time.time()
        res = func()        # 4. 拿到真正 f1 函数的返回值
        end = time.time()
        print(end - start)
        
        return res  # 5. 将 f1 函数的返回值返回给 wrapper
    return wrapper  # 5. 将实现功能的函数对象 wrapper 和 返回值 打包返回给装饰器函数 deco
f1 = deco(f1)   # 1. 将函数对象 f1 看成参数传给装饰器函数,会的到一个返回值对象使用 f1 接收,这里的 f1只是个普通的变量名,可是接收了函数对象 wrapper
res = f1() # 6. 获得了 f1 的返回值,同时获得了运行程序的时间(这里的其实是在调用装饰器函数里面的 wrapper ,已经不是原来的函数 f1 了)

2.4.3 带参数和返回值的装饰器

假设如今有一个函数 f1,比较两个数的大小,一样的添加计算程序运行的时间

def f1(x, y, z=10):
    '''被装饰函数'''
    if x > y:
        return x
    else:
        return z


f1(3, 5)  # 结果是 10
f1(5, 3)  # 结果是 5

在不改变函数的源代码及调用方式的前提下,实现计算 f1 功能耗费的时间

实现方法以下:

def f1(x, y, z=10):
    if x > y:
        time.sleep(1)
        return x
    else:
        time.sleep(2)
        return z


f1(3, 5)  # 结果是 10
f1(5, 3)  # 结果是 5


def deco(func): # 2. 这里的 func 其实是真正的 f1 函数对象
    '''装饰器'''
    def wrapper(*args, **kwargs):   # 3. 添加须要实现的功能,使用*args, **kwargs接收全部原函数可能传进来的值
        start = time.time()
        res = func(*args, **kwargs)     # 4. 使用*args, **kwargs打散全部可能传进来的参数
        end = time.time()
        print(end - start)
        
        return res  # 5. 将 f1 函数的返回值返回给 wrapper
    return wrapper  # 5. 将实现功能的函数对象 wrapper 和 返回值 打包返回给装饰器函数 deco
f1 = deco(f1)   # 1. 将函数对象 f1 看成参数传给装饰器函数,会的到一个返回值对象使用 f1 接收,这里的 f1只是个普通的变量名,可是接收了函数对象 wrapper
res = f1(5, 3) # 6. 获得了 f1 的返回值,同时获得了运行程序的时间(这里的其实是在调用装饰器函数里面的 wrapper ,已经不是原来的函数 f1 了)
print(res)
相关文章
相关标签/搜索