装饰器函数
本节导读
- 命名空间
- 闭包概念
- 装饰器
一 命名空间
又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方
名称空间共3种,分别如下
- locals: 是函数内的名称空间,包括局部变量和形参
- globals: 全局变量,函数定义所在模块的名字空间
- builtins: 内置模块的名字空间
不同变量的作用域不同就是由这个变量所在的命名空间决定的。
作用域即范围
- 全局范围:全局存活,全局有效
- 局部范围:临时存活,局部有效
查看作用域方法 globals(),locals()
LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
- locals 是函数内的名字空间,包括局部变量和形参
- enclosing 外部嵌套函数的名字空间
- globals 全局变量,函数定义所在模块的名字空间
- builtins 内置模块的名字空间
二 闭包
在函数外部执行函数内部的函数,并且还可以用函数内部作用域里的所有的值称为闭包
闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
三 装饰器
作用:在不改变源代码的情况下为函数增加功能,遵循软件开发中的一个原则“开放-封闭”原则
- 封闭:已实现的功能代码块不应该被修改
- 开放:对现有功能的扩展开放
import time def show_time(f): # 查看执行时间的函数 def inner(): start = time.time() f() end = time.time() print("spend %s" % (end - start)) return inner @ show_time # 相当于foo = show_time(foo) def foo(): x = 10 print(x) time.sleep(3) foo()
注意:
- 装饰器必须采用至少双层函数,采用返回inner的方式
- @符号 @show_time = {foo =show_time(foo)} 写在原功能函数前面
- 功能函数内有参数,相应装饰器函数也应该对应加参数
带参数的装饰器
通过多层函数的嵌套,来达到添加参数的目的
def logger(flag=""): def show_time(f): #查看执行时间的函数 def inner(): start = time.time() f() end = time.time() print("spend %s" % (end - start)) if flag =="True": print("日志记录") return inner return show_time
@logger("true")