闭包: 在函数内部再定义一个函数,并且这个函数用到了外边的函数的变量,那么将这个函数以及用到的 一些变量称之为闭包。 例子一枚: def test(number): print("----------1--") def test_in(number2): print("----------2--") print(number+number2) print("----------3--") return test_in ret = test(100) ret(1) 返回结果为: ----------1-- ----------3-- ----------2-- 101 __slots__: 定义一个特殊的__slots__变量,来限制该class实例能添加的属性 class Person(object): __slots__ = ("name","age") 注意: 使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。 LEGB: Local - 本地函数(show_filename)内部,通过任何方式赋值的,而且没有被global关键字声明为全局变量的filename变量; Enclosing - 直接外围空间(上层函数wrapper)的本地作用域,查找filename变量(如果有多层嵌套,则由内而外逐层查找,直至最外层的函数); Global - 全局空间(模块enclosed.py),在模块顶层赋值的filename变量; Builtin - 内置模块(__builtin__)中预定义的变量名中查找filename变量; 在任何一层先找到了符合要求的filename变量,则不再向更外层查找。如果直到Builtin层仍然没有找到符合要求的变量,则抛出NameError异常。这就是变量名解析的:LEGB法则。 总结: 闭包最重要的使用价值在于:封存函数执行的上下文环境; 闭包在其捕捉的执行环境(def语句块所在上下文)中,也遵循LEGB规则逐层查找,直至找到符合要求的变量,或者抛出异常。 装饰器&语法糖(syntax sugar) 那么闭包和装饰器又有什么关系呢? 上文提到闭包的重要特性:封存上下文,这一特性可以巧妙的被用于现有函数的包装,从而为现有函数增加功能。而这就是装饰器。 一般装饰器都与语法糖相配合。语法糖的使用方式: @闭包函数的名称 装饰器: 栗子: def w1(func): print("正在装饰1") def inner(): print("--------正在验证权限1-----------") func() return inner def w2(func): print("正在装饰2") def inner(): print("--------正在验证权限2-----------") func() return inner @w1 @w2 def f1(): print("------f1----") f1() 返回: 正在装饰2 正在装饰1 --------正在验证权限1----------- --------正在验证权限2----------- ------f1---- #无参数装饰器 """ def func(functionName): print("---func--1-") def func_in(*args,**kwargs): print("---func_in--1-") functionName(*args,**kwargs) print("---func_in--2-") print("---func--2-") return func_in @func #相当于 test = func(test) def test(a,b,c): print("----test--a=%d,b=%d,c=%d----"%(a,b,c)) test(11,22,33) 返回结果为: ---func--1- ---func--2- ---func_in--1- ----test--a=11,b=22,c=33---- ---func_in--2- """ #带有返回值装饰器 """ def func(functionName): print("---func--1-") def func_in(): print("---func_in--1-") ret=functionName() #保存返回来的haha print("---func_in--2-") return ret print("---func--2-") return func_in @func def test(): print("----test--") return "哈哈" ret = test() print(ret) 返回结果为: ---func--1- ---func--2- ---func_in--1- ----test-- ---func_in--2- 哈哈 """ #使用通用的装饰器 """ def func(functionName): def func_in(*args,**kwargs): ret=functionName(*args,**kwargs) return ret return func_in @func def test(): print("----test--") return "哈哈" @func def test2(): print("----test2--") @func def test3(a): print("----test3-a=%d--"%a) test2() test3(11) 返回结果为: ----test-- 哈哈 ----test2-- ----test3-a=11--
Python闭包和装饰器以及语法糖
最新推荐文章于 2024-06-13 16:50:37 发布