zoukankan      html  css  js  c++  java
  • 流暢的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

  • 相关阅读:
    AJAX原生态编写
    oracle中分页查询
    myeclipse 2014 专业版 安装 svn插件
    List.toArray()用法详解
    数据库语句 select * from table where 1=1 的用法和作用
    setObject()用法
    Golang语言学习笔记(十四)
    Golang语言学习笔记(十三)
    Golang语言学习笔记(十二)
    Golang语言学习笔记(十一)
  • 原文地址:https://www.cnblogs.com/1314520xh/p/12820261.html
Copyright © 2011-2022 走看看