流暢的python---函數闭包
一、函数的定义及其应用
所谓函数,就是把具有独立功能的代码块组织成为一个小模块,在需要的时候调用
函数的使用包含两个步骤
1.定义函数–封装独立的功能
2.调用函数–享受封装的成果
函数的作用:在开发时,使用函数可以提高编写的效率以及代码的重用‘’
函数:函数是带名字的代码块,用于完成具体的工作 需要在程序中多次执行同一项任务时,你无需反复编写完成该任务的代码,而只需调用该任务的函数
最簡單函數:例子
def fib(n): if n<=1: return n else: return fib(n-1)+fib(n-2) a=fib(10) print (a) for i in range(1, 20): print(fib(i), end=' ') 打印结果: 55 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
闭包函数:闭包的特点就是内部函数引用了外部函数中的变量。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat May 2 23:04:22 2020
@author: root
函数名.__closure__ 在函数是闭包函数时,返回一个cell元素;不是闭包时,返回None。
"""
def func():
name=100
def inner():
print (name)
print(inner.__closure__) # (<cell at 0x0000027C14EB85E8: str object at 0x0000027C14F54960>,)
return inner
f=func()
f()
结果:
100
(<cell at 0x7f568408d050: function object at 0x7f568405c560>, <cell at 0x7f567feb9310: int object at 0x55d3c129df60>)
def line_conf(a,b): def line(x): return a*x+b return line lineA=line_conf(2,1) #y=2x+1 lineB=line_conf(3, 4) #y=3x+1 print (lineA(1)) print (lineB(1))
__closure__属性返回的是一个元组对象,包含了闭包引用的外部变量。
案例: 1、若主函数内的闭包不引用外部变量,就不存在闭包,主函数的_closure__属性永远为None:
· 若主函数内的闭包不引用外部变量,就不存在闭包,主函数的_closure__属性永远为None
def line_conf(): a=1 b=2 def line(x): print (x+1) return line l=line_conf() print (l.__closure__) #None try: for i in l.__closure__: #报错 print (i.cell_contents) except Exception as e: print ('NoneType')
若主函数没有return 子函数,就不存在闭包
def line_conf(): a=1 b=2 def line(x): print (x+1) return a+b l=line_conf() print (l.__closure__) #抛异常
闭包下保存运行环境
_list=[] for i in range(5): def fun(a): return i+a _list.append(fun) print(_list) for f in _list: print(f(1)) 只保存最后一个:y=4+a # [<function fun at 0x109690d08>, <function fun at 0x109690c80>, <function fun at 0x109690ea0>, <function fun at 0x109690d90>, <function fun at 0x10968e048>] # 5 # 5 # 5 # 5 # 5
若想输出:1,2,3,4,5 :闭包在返回时,它的所有变量已经固定了,形成一个封闭的对象,
_list=[] for i in range(5): def func(i): def f_closure(a): return i+a return f_closure _list.append(func(i)) print (_list) for f in _list: print (f(1)) # [<function func.<locals>.f_closure at 0x109690e18>, <function func.<locals>.f_closure at 0x109690c80>, <function func.<locals>.f_closure at 0x109690d08>, <function func.<locals>.f_closure at 0x109690ea0>, <function func.<locals>.f_closure at 0x109690d90>] # 1 # 2 # 3 # 4 # 5
闭包案例:
def who(name): def do(what): print (name,'say',what) return do teddy=who('teddy') angel=who('angel') teddy('yyy') angel('ggg')
日志记录器:
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(' oh ,i dont know what you want to do!') return _logging p_1_logging = log_header('project_1') p_2_logging = log_header('project_2') def project_1(): p_1_logging('yyy', 'debug') p_1_logging('bbb', 'warning') p_1_logging('ccc', 'error') def project_2(): p_2_logging('qqq', 'debug') p_2_logging('eee', 'warning') p_2_logging('yyy', 'error') project_1() project_2()
输出:
2020-05-03 11:31:27 [project_1] DEBUG yyy
2020-05-03 11:31:27 [project_1] WARNING bbb
2020-05-03 11:31:27 [project_1] ERROR ccc
2020-05-03 11:31:27 [project_2] DEBUG qqq
2020-05-03 11:31:27 [project_2] WARNING eee
2020-05-03 11:31:27 [project_2] ERROR yyy
心有猛虎,细嗅蔷薇