ITS·黑客

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

2017-05-13  本文已影响14人  MJXH

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

下面是闭包的栗子:

#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

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

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

上一篇 下一篇

猜你喜欢

热点阅读