您的位置:首页 > 编程语言 > Python开发

老男孩Python笔记_10

2019-05-08 19:38 134 查看

文章目录

  • 函数的嵌套
  • 闭包函数
  • locals() 和 globals()

    locals ()

    获取当前作用域的所有变量

    • locals 如果在函数的外面,获取locals()返回值打印之前, 所有的内容.
    a = 10
    b = 20
    res = locals()
    c=20
    print(res)
    d=30
    • locals 如果在函数的里面,获取locals调用之前,所有的内容
    def func():
    f1 = 11
    f2 = 12
    res = locals()
    f3 = 13
    print(res)
    func()

    globals ()

    只获取全局变量(无论在函数内外都只获取全局变量)

    • globals 如果在函数的外面,获取globals()返回值打印之前, 所有的内容
    a = 5
    b  =15
    res = globals()
    c = 26
    print(res)
    d = 27
    • globals 如果在函数的里面,获取globals调用之前,所有的内容
    z1 = 5
    z2 = 6
    def func():
    f1 = 1
    f2 = 2
    f3 = 3
    res = globals()
    f4 = 6
    print(res)
    z4 = 8
    func() #res = globals()
    z3 = 7
    • globals 动态创建全局变量
      globals 返回的是系统的 全局命名空间的字典 ,在空间里面放的全局变量
    dic = globals()
    print(dic,type(dic))
    dic['wangwen'] = 188
    print(wangwen)
    • globals 可以批量创建全局变量
    def func():
    res = globals()
    # res['a1'] = 1
    # res['a2'] = 2
    for i in range(5):
    # print(i)
    res["a%d" % (i) ] = i
    '''
    "a%d" % (i)  # 字符串的格式化
    
    res['a0'] = 0
    res['a1'] = 1
    res['a2'] = 2
    res['a3'] = 3
    res['a4'] = 4
    '''
    
    func()
    print(a0)
    print(a1)
    print(a2)
    print(a3)
    print(a4)

    locals 更多的用于获取一些变量 , globals更多的用于修改一些变量

    函数的嵌套

    嵌套在外层,称之外函数
    嵌套在里层,称之内函数

    def outer():
    
    def inner():
    print("我是inner函数")
    inner()
    
    outer()

    (1)内部函数可以直接在函数外部调用么 不可以
    (2)调用外部函数后,内部函数可以在函数外部调用吗 不可以
    (3)内部函数可以在函数内部调用吗 可以
    (4)内部函数在函数内部调用时,是否有先后顺序 有顺序

    无论在函数内还是函数外:都要遵循先定义再调用的顺序

    def outer():
    # a = 16
    # id = 99
    def inner():
    # a = 15
    def smaller():
    # a = 10
    print(id)
    print("我是smaller函数")
    smaller()
    inner()
    
    outer()

    LEGB (就近找变量原则)

    找寻变量的调用顺序采用LEGB原则(即就近原则)
    B —— Builtin(Python):Python内置模块的命名空间 (内建作用域) (内建命名空间)
    G —— Global(module):函数外部所在的命名空间 (全局作用域) (全局命名空间)
    E —— Enclosing function locals:外部嵌套函数的作用域 (嵌套作用域) (局部命名空间)
    L —— Local(function):当前函数内的作用域 (局部作用域) (局部命名空间)
    依据就近原则,从下往上 从里向外 依次寻找

    额外注意点
    如果先前局部变量存在a,删除之后再获取就获取不到,
    如果先前不存在该局部变量,默认向上按照LEGB原则依次寻找

    a = 10
    def func():
    a = 20
    del a
    # print(a)
    func()
    # print(a)

    闭包函数

    闭包:
    内函数使用了外函数的局部变量,
    并且外函数把内函数返回出来的过程是闭包
    这个内函数叫做闭包函数;

    基本语法

    def outer():
    a = 5
    b = 6
    # inner 是闭包函数
    def inner():
    print(a,b)
    return inner
    res = outer()  # res = inner
    res()          # res() = inner()
    • 获取闭包函数使用的变量
      __closure__ , cell_contents (了解)
    tup = res.__closure__
    
    print(tup)
    # 获取元组里面第一个元素
    obj = tup[0]
    print(obj)
    # 使用cell_contents来获取单元对象当中的值
    res = obj.cell_contents
    print(res)
    
    obj2 = tup[1]
    res2 = obj2.cell_contents
    print(res2)

    闭包函数特点

    内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长该变量的生命周期
    (实际内存给它存储了这个值,暂时不释放)

    def majunqiang_family():
    dajie = "马蓉"
    erjie = "马冬梅"
    kuang = "金矿"
    # money 局部变量因为在闭包函数中使用,于是发生绑定,延长该变量的生命周期
    money = 1000
    
    def dajie_hobby():
    nonlocal money
    money -= 900
    print("大姐喜欢花钱,喜欢买兰博基尼,喜欢买比基尼,喜欢买channel,家里钱还剩下%d" % (money))
    
    def erjie_hobby():
    nonlocal money
    money += 500
    print("二姐马冬梅喜欢赚钱,喜欢上长春扎疫苗,因为假疫苗能赔偿,喜欢卖血,5块钱一瓶,家里钱赚了%d" % (money))
    
    def master():
    # 返回一个元组,元组里面的每一个元素是函数
    return (dajie_hobby,erjie_hobby)
    
    return master
    
    func = majunqiang_family()
    tup = func()
    print(tup)
    # 大姐函数
    dajie = tup[0]
    dajie()
    # 二姐函数
    erjie = tup[1]
    erjie()

    闭包的特点意义

    • 闭包的特点
      内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长该变量的生命周期
      (实际内存给它存储了这个值,暂时不释放)
    def outer(num):
    
    def inner(val):
    return num + val
    return inner
    
    func = outer(10)  # func = inner
    res = func(21)   # func(21) = inner(21)
    print(res)       # res = num + val =  10 + 21 = 31
    '''
    代码解析:
    num 接收到普通实参10 此刻 num = 10
    func = outer(10)  # func = inner
    res = func(21)    # func(21) = inner(21)
    print(res)        # res = num + val =  10 + 21 = 31
    '''
    • 闭包的意义

    模拟鼠标点击的操作

    • 如果使用全局变量num来进行统计,因为作用域太大,容易造成漏洞.不安全
    # 如果使用全局变量num来进行统计,因为作用域太大,容易造成漏洞.不安全
    num = 0
    def click_num():
    global num
    num+=1
    print(num)
    # 调用一次函数,累加一次num
    click_num()
    click_num()
    click_num()
    
    num = 100
    click_num()
    click_num()
    • 闭包的意义:闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.
    def click_num():
    num = 0
    def func():
    nonlocal num
    num+=1
    print(num)
    return func
    
    click_num = click_num()
    click_num()
    click_num()
    click_num()
    num = 100
    click_num()
    click_num()
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: