美文网首页ITS·黑客
【python】闭包&LEGB法则、装饰器&语法

【python】闭包&LEGB法则、装饰器&语法

作者: MJXH | 来源:发表于2017-05-13 22:37 被阅读14次

    所谓闭包,就是将组成函数的语句和这些语句的执行环境打包在一起时,得到的对象。

    下面是闭包的栗子:

    #foo.py foo文件
    filename = 'foo.py'
    def call_func(f):     #这个函数就是说,要返回调用那个作为参数的函数
        return f()
    
    #func.py    另一个叫func的文件 
    import foo   #在这里导入上一个 foo 文件
    filename = 'func.py'      
    def show_filename():
        return "filename: %s" %filename
    print( foo.call_func(show_filename))  # 返回:filename: func.py
    #注意:实际发生调用的位置,是在foo.call_func函数里
    

    这个栗子就是想说明,有两个文件foo 和 func,其中都有一个同名filename的定义。在func文件中导入了foo文件后,运行foo.call_func(show_filename),尽管实际调用show_filename的位置在foo.py的call_func内部,但是所返回的filename是在func文件中定义的那个。
    在下面这个嵌套函数中看

    #enclosed.py
    import foo   # 导入了poo 文件,call_func功能:  返回调用作为参数的函数
    def wrapper():    #这个wrapper函数没有返回值,打印调用那个call_func函数
         filename = "enclosed.py"  #嵌套函数内部也有一个同名filename变量
         def show_filename():
               return "filename: %s" % filename   #执行到这句的时候,就要开始找,究竟用哪个 filename
         print foo.call_func(show_filename)      #输出:filename: enclosed.py
    

    举这个栗子想说明:闭包将会捕捉内层函数执行所需的整个环境

    • LEGB法则就是查找顺序。
      当代码执行到filename: %s" % filename时,解释器按照循序查找filename变量:
        先在show_filename函数中找,然后是到wrapper函数中找(多层嵌套的话,就由内而外查找),然后到enclosed.py中找,最后到内置模块。按顺序一旦找到就不在到外层去找了,如果一直找不到,那就会出现NameError异常。

    • 装饰器&语法糖就是@log
      提到闭包的重要特性:封存上下文,这一特性可以巧妙的被用于现有函数的包装,从而为现有函数更加功能。而这就是装饰器。
      (原本想找资料加深对装饰器的理解,但是,现在这个就拿来读读吧)

    import logging  #这个模块没具体查,是跟记录日志有关的
    logging.basicConfig(level = logging.INFO)
    #通过logging.basicConfig函数对日志的输出格式及方式做相关配置
    def add(a,b):  #这个add函数是要被“装饰的”
        return a+b
    def checkParams(fn): #通过封存的fn,继续调用原始的add进行+运算。
        def wrapper(a,b):
            if isinstance(a,(int,float)) and isinstance(b,(int,float)):##检查参数a和b是否都为整型或浮点型  isinstance函数的使用
                return fn(a,b)   #是则调用fn(a, b)返回计算结果
                                 #否则通过logging记录错误信息,并友好退出
            logging.warning("variable 'a' and 'b' cannot be added")
            return
        return wrapper   #fn引用add,被封存在闭包的执行环境中返回
    #将add函数对象传入,fn指向add
    #等号左侧的add,指向checkParams的返回值wrapper
    add = checkParams(add)   #这里一般会被写成语法糖简化
    add(3,'hello')
    

    诶。。。乱七八糟。。的
    看这个吧https://www.zhihu.com/question/25950466

    相关文章

      网友评论

        本文标题:【python】闭包&LEGB法则、装饰器&语法

        本文链接:https://www.haomeiwen.com/subject/xquatxtx.html