一、闭包的概念
简而言之, 闭包的特点就是内部函数引用了外部函数中的变量。
简单粗暴地理解为闭包就是一个定义在函数内部的函数,闭包使得变量即使脱离了该函数的作用域范围也依然能被访问到。
二、闭包函数的必要条件:
1、闭包函数必须返回一个函数对象
2、闭包函数返回的那个函数必须引用外部变量(一般不能是全局变量),而返回的那个函数内部不一定要return
一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。
但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
def line_conf(a, b):
def line(x):
return a*x + b
return line
line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5))
print(line2(5))
这个例子中,函数line与变量a,b构成闭包。在创建闭包的时候,我们通过line_conf的参数a,b说明了这两个变量的取值,这样,我们就确定了函数的最终形式(y = x + 1和y = 4x + 5)。我们只需要变换参数a,b,就可以获得不同的直线表达函数。
由此,我们可以看到,闭包也具有提高代码可复用性的作用。
三、闭包函数的判断
函数名.closure 在函数是闭包函数时,返回一个cell元素;不是闭包时,返回None。
输出cell:
def func():
name = 'python'
def inner():
print(name)
print(inner.__closure__)
return inner
f = func()
f()
输出None:
name = 'python'
def func():
def inner():
print(name)
print(inner.__closure__) # None
return inner
f = func()
f()
4、闭包实现快速给不同项目记录日志
实例
import logging
def log_header(logger_name):
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s [%(name)s] %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
logger = logging.getLogger(logger_name)
def _logging(something,level):
if level == 'debug':
logger.debug(something)
elif level == 'warning':
logger.warning(something)
elif level == 'error':
logger.error(something)
else:
raise Exception("I dont know what you want to do?" )
return _logging
project_1_logging = log_header('project_1')
project_2_logging = log_header('project_2')
def project_1():
#do something
project_1_logging('this is a debug info','debug')
#do something
project_1_logging('this is a warning info','warning')
# do something
project_1_logging('this is a error info','error')
def project_2():
# do something
project_2_logging('this is a debug info','debug')
# do something
project_2_logging('this is a warning info','warning')
# do something
project_2_logging('this is a critical info','error')
project_1()
project_2()
#输出
2018-05-26 22:56:23 [project_1] DEBUG this is a debug info
2018-05-26 22:56:23 [project_1] WARNING this is a warning info
2018-05-26 22:56:23 [project_1] ERROR this is a error info
2018-05-26 22:56:23 [project_2] DEBUG this is a debug info
2018-05-26 22:56:23 [project_2] WARNING this is a warning info
2018-05-26 22:56:23 [project_2] ERROR this is a critical info
闭包思考:
1.闭包似优化了变量的传递,原来需要类对象完成的工作,闭包也可以完成;
2.由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存