Python闭包和装饰器以及语法糖

闭包:
    在函数内部再定义一个函数,并且这个函数用到了外边的函数的变量,那么将这个函数以及用到的
    一些变量称之为闭包。
    例子一枚:
        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--

猜你喜欢

转载自blog.csdn.net/weixin_42238444/article/details/80643043
今日推荐