20190923 闭包与装饰器

闭包函数

闭包函数:把函数内部的变量+闭包函数内部的函数 这两者包裹在一起,然后通过返回值的形式返出来。

1. 内部函数可以引用外部函数的参数和局部变量,当外部函数返回了内部函数时,相关参数和变量都保存在返回的函数中。
2. 是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。

实例

# print_msg是外围函数
def print_msg():
    msg = "I'm closure"

    # printer是嵌套函数
    def printer():
        print(msg)

    return printer


# 这里获得的就是一个闭包
closure = print_msg()
# 输出 I'm closure
closure()

msg是一个局部变量,在print_msg函数执行之后应该就不会存在了。但是嵌套函数引用了这个变量,将这个局部变量封闭在了嵌套函数中,这样就形成了一个闭包。

普通打印url函数式
def s1(url):
    print(url)
    
f1('www.baidu.com')
f1('www.sougou.com')

闭包函数
def f1(url):
    def s1():
        print(url)  # 这里想打印的是url
    return s1     #函数对象


taobao = f1(‘www.sohu.com’)  # f1就是s1函数
taobao()

baidu = f1(‘www.baidu.com’)
baidu()

装饰器

装饰器:给函数增加一个额外的功能的函数特点

  1. 装饰器本身就是函数,用来装饰被装饰的函数。
  2. 不改变原函数的源代码
  3. 不改变原函数的调用方式

装饰器的使用:

  • 先定义一个装饰函数
  • 再定义你的业务函数
  • 最后使用语法糖调用函数

入门用法:日志打印器

装饰函数:就是给业务函数增加的一个功能函数,他打印了日志流程

# 这是装饰函数
def logger (func):  # add函数传值
    def wrapper(*arg,**kw):
        print('计算函数')
        # 真正执行的是这一行
        func(*arg,**kw)  # 相当于add函数
        
        print ('计算结束')
    return wrapper
 

业务函数是被装饰的主体函数,在这里是计算两数之和,写完可以直接语法糖指向装饰函数。

@ logger
def add(x,y):
    print (x+y)

最后执行函数

add(200,50)

输出结果

计算函数
80
计算结束

入门用法:时间计时器

计算一个函数的执行时长

# 装饰函数
def timer(func):
    def wrapper(*arg,**kw):
        start = time.time()
        func(*arg,**kw)
        end = time.time
        
        time_z = end - start
        print(f'共花费{time_z}')
    return wrapper

# 业务代码
import time
@timer
def index():
    '''业务代码'''
    print('12121')
    time.sleep(1)

# index = timer(index)
index()
# 输出
'''
12121
共花费1.0008752346038818
'''

两层装饰器

  1. 用来装饰函数的,他的本质是函数
  2. 不改变函数的源代码
  3. 不改变函数的调用方式

装饰器模板

def deco(func):
    def wrapper(*args,**kwargs):
        # 想要添加的功能
        res = func (*args,**kwargs)
    	return res
	return wrapper

@ deco

装饰器语法糖@

原文地址:https://www.cnblogs.com/fwzzz/p/11574609.html