zoukankan      html  css  js  c++  java
  • 浅谈闭包函数

    1.函数对象

    函数对象的定义:把函数的地址当做一种函数的变量名去使用,就是函数对象。

    引用函数对象通常有4种方法,分别是:

    1.直接将函数名赋值给一个变量:

    def func1():
        print('from func1')
    func2 = func1
    func2()
    
    
    此时func2这个变量的值便是func1这个函数的内存地址,
    func2后面加个括号就等于对func1加上了括号,只是此
    时调用的方式不一致,这种方法在后面的装饰器部分也又用到。
    这个代码的运行结果是:
    from func1

    2.可以当做参数传给另外一个函数:

    def func1():
        print('from func1')
    
    def bar(xxx):
        # print(xxx)
        xxx()
    
    bar(func1)
    
    如上述代码,在调用bar函数时,我们传入了另外一个函数func1,
    在bar函数中,我们既输出了传入函数对象既func1的内存地址,
    也对存入的函数对象进行了调用,最终结果为:
    
    <function func1 at 0x000001DB32915598>
    from func1

    3.可以作为某个特定函数的返回值:

    def fn1():
        print('from func')
    
    def bak():
        return fn1
    
    f = bak()
    
    f()

    4.可以当作容器类型的元素:在选择功能的时候可以使用这种方式,技能方便修改,也能减少代码量。

    # 定义方法进行四则运算
    # 定义加法功能
    def add(a,b):
        return a+b
    
    #定义加法功能
    def low(a,b):
        return a-b
    
    # 定义乘法功能
    def jump(a,b):
        return a*b
    
    # 定义除法功能
    def full(a,b):
        return a/b
    
    # 定义取余功能
    def mod(a,b):
        return a%b
    
    # 定义四则运算功能法则
    def computed(fn,n1,n2):
        res =fn(n1,n2)
        return res
    
    # 定义容器,来封装功能
    cmd_dic ={
           'add':add,
           'low':low,
           'jump':jump,
           'full':full,
           'mod':mod
    }  
    
    # 根据指令获得计算方法
    def get_cp_fn(cmd):
        if cmd in cmd_dict:
            return cmd_dict[cmd]
        return add   # 输入有误采用默认方法  
    
    
    while True:
            cmd = input('cmd:>>>>>>')
            if cmd not in cmd_dic:
                break
            cp_fn = get_cp_fn[cmd]
            res = computed(cp_fn,100,20)
            print(res)
    
    
    # 得到的运算结果为:========================
    120
    80
    2000
    5.0
    0
    =====================================

    2.函数的嵌套

    1.函数的嵌套分为两种:嵌套定义和嵌套调用。

    2.函数的嵌套调用:在函数中调用了其他的函数。

    # 求两个数的最大值
    def max2(a,b):
        if a > b:
            return a
        return b
    
    # 求三个数的最大值
    def max3(a,b,c):
        res = max2(a,b)
        return max2(res,c)

    3.函数的嵌套定义:在函数内定义了其他的函数

    from math import pi
    
    def circle(radius,mode=0):
        def perimiter(radius):
            return 2 * pi * radius
    
        def area(radius):
            return pi * (radius ** 2)
    
        if mode == 0:
            return perimiter(radius)
        elif mode == 1:
            return area(radius)
    
    我们将求圆的周长与圆的面积的函数定义在了一个大
    函数circle中,只需要选择在circle函数中传入的参数
    我们就可以选择我们需要调用的函数。

    3.名称空间

    定义:存放名字与内存地址绑定关系的地方

    名称空间分为三类:

    1.内置名称空间:存储解释器自带的一些名称与值的对应关系

        (python解释器启动时创建 所有代码全部执行完毕 关闭解释器时 销毁)

    2.全局名称空间:只要你的名字的定义是顶着最左边写的就在全局空间(如果if顶级,那么if中的变 量名也属于全局名称空间)(执行py文件创建全局名称空间 关闭解释器时 销毁)

    3.局部名称空间:只要是函数内的名称就是局部的

         (调用函数时创建 函数执行完毕就销毁)

        名称空间的加载顺序:内置的 ->   全局的 ->   局部的(LEGB规则)

        名称的查找顺序:从当前位置往外一层一层的查找

             如果当前处于局部名称空间:当前位置所在的局部----->全局------->内置

             如果当前处于全局名称空间:全局------->内置

    4.作用域

    定义:域指的是区域,范围的的意思.。作用域就是名称空间的范围

    作用域的分类:1.全局作用域  2.局部作用域

    1.全局作用域:包含内置与全局名称空间的名字   特点:全局存活,全局有效

    2.局部作用域:包含局部名称空间的名字    特点:临时存活,局部有效

    特别注意:作用域的关系在函数的定义阶段就已经存在固定死了,与调用位置无关!!!

    def f1():
        print(xxx)
    xxx=111
    def f2():
        xxx=222
        f1()
    f2()
    
    调用函数f2时,这个代码的运行结果为111,因为在函数定义时,
    f1中有一个print(xxx),但是在f1函数这个局部作用域中并没
    有xxx这个变量,所以它会向外部(全局作用域)中区寻找,返现
    xxx=111,所以在调用f2时,输出结果会是111,因为在函数定义的时候已经固定死了

    5.闭包

    定义:闭函数:该函数一定是定义在函数内的函数

         包函数:该内部函数包含对外层函数作用域名字的引用

     闭包函数模板:

    def outer():
        x = 10
        def inner():
            print(x)    
        return inner

    闭包函数也可以为函数体传值:

    def outter(x):
        def inner():
            print(x)
        return inner

    global是在局部变量中声明变量是全局变量,并且可以在局部变量中修改全局变量的值;而nonlocal在局部变量中声明变量是外层函数变量(永远都不会找到全局变量中)

  • 相关阅读:
    py.turtle学习笔记(简单图形绘制)
    eclipse Network Connections
    EntityFramework 6 使用注意事项汇总
    Web发展过程中的一些设计思想和软硬件系统构建方式的一段话
    Fody is only supported on MSBuild 16 and above. Current version: 15
    .net 程序优化的原则-C#语言元素相关
    .net 事务
    关于IIS部署网站后 浏览器HTTP 错误 404.7 请求筛选模块被配置为拒绝该文件扩展名。
    准备学习的书籍列表
    在本地搭建Git厂库并把自己得代码上传到远程厂库
  • 原文地址:https://www.cnblogs.com/wanglei957/p/10636765.html
Copyright © 2011-2022 走看看