• 函数对象,名称空间,作用域,和闭包


    一、函数对象

    1、函数对象:函数名存放的就是函数的地址,所以函数名也是对象,称之为函数对象

    a = 10
    print(a,id(a))
    
    def fn():
        num = 10
        print('fn fuction run')
    print(fn())
    
    b = a
    print(b,id(b))

    2、函数对象的四个应用

    ①可以直接被引用fn=cp_fn

    def fn():
        num = 10
        print('fn function run')
    print(fn)
    
    def fn():
        num = 10
        print('fn function run')
    
    func = fn
    print(fn)
    print(func)

    ②可以当做函数参数传递computed(cp_fn,a,b)

    # 通过该函数可以对任意两个数的四则运算某一运算
    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 computed(fn,a,b):   # fn代表四则运算的一种,res为运算结果
        res = fn(a,b)
        return res
    
    while True:
        cmd = input('cmd:>>>')
        if cmd =='add':
            result=computed(add,100,200)
        elif cmd =='low':
            result=computed(low,100,200)
        elif cmd =='jump':
            result=computed(jump,100,200)
        elif cmd =='full':
            result=computed(full,100,200)
        else:
            print('输入有误')
        print(result)

    ③可以作为容器类型的元素

    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 quyu(a,b):
        return a %b
    def computed(fn,a,b):
        res = fn(a,b)
        return res
    method_map={
        'add':add,
        'low':low,
        'jump':jump,
        'full':full,
        'quyu':quyu,
    }
    
    while True:
        cmd = input('cmd:')   # 用户输入的指令只要有对应关系,就会自动取走计算方法
        if cmd in method_map:          # 这样外界就不关心有哪些计算方法
            cp_f = method_map[cmd]
            result = computed(cp_fn,100,200)
            print(result)
        else:
            print('输入错误')
            break

    ④可以作为函数的返回值

    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 quyu(a,b):
        return a%b
    
    def computed(fn,a,b):
        res = fn(a,b)
        return res
    
    method_map = {
       'add':add,
        'low':low,
        'jump':jump,
        'full':full,
        'quyu':quyu,
    }
    # 根据指令获取计算方法
    def get_cp_fn(cmd):
        if cmd in method_map:
            return method_map[cmd]    # 返回的是method_map中的’cmd’对应的值cmd
        return jump                   # 输入有误就采用jump
    
    while True:
        cmd = input('cmd:')
        if cmd =='quit':
            break
        cp_fn = get_cp_fn(cmd)
        result = computed(cp_fn,100,200)
        print(result)

    二、名称空间

    print(len('abc'))     # 结果为 3
    len = len('abcsdf')
    print(len)            # 结果为 6
    del len
    print(len('abc'))     # 结果为 3
    
    def fn1():
        len = 100
        print(len)
    
    def fn2():
        len = 200
        print(len)
    fn1()
    fn2()

    1、定义:存放名字与内存空间地址对应关系的容器

    2、作用:解决由于名字有限,导致名字重复发送冲突的问题

    3、三种名称空间:

    ①build-in:内置名称空间,系统级,一个,随解释器执行而产生,解释器停止而销毁
    ②global:全局名称空间,文件级,多个,随所属文件加载而产生,文件运行完毕而终止
    ③local:局部名称空间,函数级,多个,随所属函数执行而产生,函数执行完毕而销毁
    加载顺序:build-in>global>local

    4、global关键词

      可以将local的名字提升为global的名字。一个文件中的global名字就是一个,所以函数内外部使用的名字都是一个

      注意:一定要调用函数,才能产生函数,并提升

    # part1
    len =1000
    def fn():
        len = 200
        print(len)
    fn()              # 结果为200
    print(len)        # 结果为1000
    
    
    # part2
    l = []
    def fn():
        l=[]
        l.append(200)
        print(l)
    fn()             # 结果为 [200]
    print(l)         # 结果为[]
    
    # 定义一个函数,函数中有一个变量
    def fn1():
        num = 200
        return num
    fn1()
    # 在定义一个函数,该函数使用上一个函数的变量
    def fn2():
        print(num)
    num = fn1()
    fn2()
    
    
    # part3
    num = 100
    def fn1():
        global num #100     # 将logal:num>global:num  # 将局部上升到全局
        num=200
        num=300
    # num=300
    def fn2():              # logal中的名字一旦global,就变成global的名字,一个文件中的global就是一个
        global num #300
        num = 400
        print(num)
    # num=400
    fn1()
    print(num)     # 结果为300
    fn2()
    print(num)     # 结果为300 400 400

    三、作用域

    1、定义:名字起作用的范围

    2、作用:解决名字可以共存问题

    3、四种作用域

    ①build-in:内置作用域,所有文件所有函数
    ②global:全局作用域,当前文件所有函数
    ③local:局部作用域,当前函数
    ④enclosing:嵌套作用域,当前函数与当前函数的内部函数
    len = 100
    def outer():
        len = 200
        def inner():
            len =300
            print('1',len)     # 结果为300
        inner()
        print('2',len)         # 结果为200
    outer()
    print('3',len)             # 结果为100
    
    del len
    print('4',len)             # 4 <built-in function len>

    4、不同作用域之间名字不冲突,以达到名字的重用

    查找顺序:local>enclosing>glocal>build-in

    四、函数的嵌套定义和闭包

    1、函数的嵌套定义:将函数直接定义到另一个函数的内部,可以使用外部函数中的名字

    def fn1():
        num = 200
        def fn2():   # fn2就可以直接使用fn1中的名字
            print(num)
        fn2()
    fn1()

    2、闭包:

    ①closure:被包裹的函数称之为闭包。定义在函数内部的函数

    ②完整的闭包结构:

    将函数进行闭包处理

    提升函数名的作用域,将内部函数对象作为外部函数的返回值

    def a():
        def b():
            print("cc")
        return b
    a()        #a()=b          
    y = a()()    # a()() =b()
    y             # 结果为 cc
    
    
    def a():
        def b():
            def c():
                def d():
                    print('dddd')
                return d
                print("ccc")
            return c
        return b
    a()       # b
    a()()     #b()
    a()()()   #b()() = c()
    a()()()
    y=a()()()()
    y         # 结果为 dddd
  • 相关阅读:
    master线程的主循环,后台循环,刷新循环,暂停循环
    InnoDB的后台线程(IO线程,master线程,锁监控线程,错误监控线程)和内存(缓冲池,重做日志缓冲池,额外内存池)
    MySQL的连接方式
    编写高质量的 Java 代码
    TProfiler
    Copy-On-Write容器
    G1 垃圾收集器
    JAVA 虚拟机钩子
    Future和Promise
    算法笔记_134:字符串编辑距离(Java)
  • 原文地址:https://www.cnblogs.com/zhangguosheng1121/p/10638686.html
Copyright © 2020-2023  润新知