流暢的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

原文地址:https://www.cnblogs.com/1314520xh/p/12820261.html