python中的命名空间,作用域和lambda匿名函数详解

1 篇文章 0 订阅
0 篇文章 0 订阅

命名空间的定义

命名空间指的是保存程序中的变量名和值的地方。
命名空间的本质是一个字典, 用来记录变量名称和值。
字典的 key 是变量的名称,字典的 value 对于的是变量 的值。 例如 {‘name’:’zs’,’age’:10}
命名空间一共分为三种:局部命名空间、全局命名空间、内置命名空间
1,局部空间: 每个函数都有自己的命名空间,叫做局部空间,它记录了函数的变量,包括函数 的参数 和局部定义的变量
2,全局空间: 每个模块拥有它自已的命名空间,叫做全局命名空间,它记录了模块的变量,包 括函数、 类、其它导入的模块。
3,内置名称空间: 任何模块均可访问它,它存放着内置的函数和异常。

命名空间的访问:

1,局部名称空间使用 locals() 函数来访问
2,全局命名空间的访问使用 globals()函数访问
(print这两货就行了)

命名空间加载顺序

内置命名空间(程序运行前加载)->
全局命名空间(当程序运行的时候加载全局命 名空间)->
局部命名空间(程序运行中:函数被调用时才加载)

命名空间查找顺序

局部命名空间中找,如果能找到则停止搜索
如果找不到
全局命名空间中查找,如果找到则停止搜索
如果找不到
内置命名空间中查找,如果找不到则报错。

嵌套函数的情况:
1、先在当前 (嵌套的或 lambda) 函数的命名空间中搜索
2、然后是在父函数的命名空间中搜索
3、接着是模块命名空间中搜索
4、最后在内置命名空间中搜索
在这里插入图片描述

作用域的定义

作用域指的是变量在程序中的可应用范围。 作用域按照变量的定义位置可以划分为 4 类即 LEGB:
1, Local(函数内部)局部作用域。
2, Enclosing(嵌套函数的外层函数内部)嵌套作用域(闭包)。
3, Global(模块全局)全局作用域。
4,Built-in(内建)内建作用域。(指的是 builtins.py 模块)

在这里插入图片描述
内层作用域可以访问外层作用域,然外层作用域不能访问内层作用域,切记切记

在 python 中,模块(module),类(class)、函数(def、lambda)会产生新的 作用域,其他代码块是不会产生作用域的,
也就是说,类似条件判断(if……else)、 循环语句(for x in data)、异常捕捉(try…catch)等的变量是可以全局使用的。

全局变量和局部变量

在函数中定义的变量称为局部变量,只在函数内部生效,
在程序一开始定义的变量称为全局变量,全局变量的作用域是整个程序。
全局变量是不可变数据类型,函数无法修改全局变量的值
全局变量是可变数据类型,函数可以修改全局变量的值
当然,你可以使用global 和 nonlocal 关键字改变这一点,具体可以看我的博客其他文章:python基础知识回顾

嵌套作用域和 lambda

lambda 表达式也会产生一个新的局部作用域。
在 def 定义的函数中嵌套 labmbda 表达式,lambda 表达式能够看到所有 def 定义的函数中可用的变量。
给一个经典面试题:

def test():
    l1 = []
    for i in range(5):
        l1.append(lambda n:i**n)
    return l1

t = test()
print(t[0](2))
print(t[1](2))
print(t[2](2))
print(t[3](2))
print(t[4](2))

请给出打印的结果

16
16
16
16
16

5个16,知道为什么吗?我做一点小改动

def test():
    l1 = []
    for i in range(5):
        l1.append(lambda n,i=i:i**n)
    return l1

t = test()
print(t[0](2))
print(t[1](2))
print(t[2](2))
print(t[3](2))
print(t[4](2))

结果

0
1
4
9
16

现在想通了吗?
这里是一个E的作用域,lambda也有一个内部的作用域,在外层test函数的嵌套作用域内,
列表中加入的都是lambda函数的地址,并没与调用这个函数,因为嵌套作用域中的变量在嵌套的函数被调用时才进行查找,所以他们实际上记住的是同样的值(在最后一次循环选代中循环变量的值)。也就 是说,我们将从列表中的每个函数得到 4 的平方的函数。
那么后面的改动做了些什么事情呢?匿名函数将嵌套作用域中的 “ i ”的变量赋予给了自己内部的“ i ”的变量,记忆了下来,列表在添加lambda对象的时候,也保存了其“ i ”值,所以最后调用的时候就能得到我们预期的结果了!!!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值