关于locals()和globals()的记录

locals()陷阱

可以简单理解为locals()只读,globals()可读可写,因此操作locals()生成动态变量不可行,但是操作globals()生成动态变量可行,且globals()全局共用

def test():globals()['a'] = 1locals()['b'] = 2test()
print(a)
print(b)
--------------------------------------
1
Traceback (most recent call last):File "C:/Users/wayne/Desktop/StereoConstruction/testlocalglobal.py", line 12, in <module>print(b)
NameError: name 'b' is not defined

exec作用域问题

def exec(cmd, globals=None, locals=None):......

exec函数原型如上,

当不传递globals和locals时,exec会继承上文的locals和globals

当只传递globals时,exec会给globals自动添加__builtin__等内置内容并复制一份给locals

当globals和locals都传递时,exec会给两者都加上__builtin__等内置内容

具体的可以写点简单的代码验证

exec执行会改变下文的globals和locals,如下,

expr = """
y = 20
z = 30
print(locals())
print(globals())
"""def func():exec(expr)x = 10print(locals())
exec(expr)
# func()
print(globals())
print(locals())print(y)
------------------------------
20

此处可行因为在exec中会改变globals()的值从而可以拿到新的变量

但是如果把exec放在一个函数里执行则不行,因为其改变不了globals(),如下

expr = """
y = 20
z = 30
print(locals())
print(globals())
"""def func():exec(expr)x = 10print(locals())
# exec(expr)
func()
print(globals())
print(locals())print(y)
--------------------------------------------
Traceback (most recent call last):File "C:/Users/wayne/Desktop/StereoConstruction/testlocalglobal.py", line 25, in <module>print(y)
NameError: name 'y' is not defined

那如果在exec中改变globals应该就可以拿到新变量了吧,如下,

expr = """
globals()['y'] = 20
"""def func():exec(expr)x = 10
func()print(y)
---------------------------------
20

可以看到确实如预料的那样

给exec传递参数

考虑如下需求场景,需要在exec函数中生成一个变量并且在下文被使用

  • 方案一

方案一就可以采用在exec中修改globals将后续要用的变量变成global变量,但是这样做的缺点也是显而易见的,增加了一个全局变量,并且由于IDE无法识别这种语法导致有红色波浪线强迫症无法接受,那么还可以怎么做呢,这个时候就可以利用exec的参数传递功能了

  • 方案二

利用exec的参数传递功能,先来看一个错误解决方案

expr = """
a = 10
"""def func():a = Noneexec(expr)print(a)func()
---------------------------------------
None

可以看到并没有完成想要的功能,为什么呢,继续分析

expr = """
print(1, locals())
a = 10
b = 20
print(2, locals())
"""def func():a = Noneexec(expr)print(3, locals())print(a)func()
--------------------------------
1 {'a': None}
2 {'a': 10, 'b': 20}
3 {'a': None, 'b': 20}
None

可以看到,由于locals()的只读特性,我们无法改变原有key='a’的值,但是可以新增key=‘b’,虽然由于只读性质这个b依旧不能被当作一个变量使用

这个时候考虑到exec可以手动传入locals()和globals(),假如我们传递一个dict代表locals或globals()进去exec会发生什么呢,分析一下

由于exec会改变得到的locals()和globals(),一般来说是locals()被改变,因为一般都是操作局部变量,而locals()又是我们传进去的dict,在exec中操作dict中对应的键的变量就相当于改变了dict的对应键的值,因此可以利用这个性质在exec内部增加一个dict的键值对或改变某个键的值,如下

expr = """
print(1, locals())
a = 10
b = 20
print(2, locals())
"""def func():a = Nonedic = {'b': None, 'c': 30}exec(expr, dic)print(3, locals())print(4, dic)print('a=', a)print('b=', dic['b'])print('a*=', dic['a'])func()
--------------------------
a= None
b= 20
a*= 10

exec需要locals()和globals()两个参数,但是对于该种应用情况来说,传哪个都无所谓,一般不用传两个以免造成阅读困难,因为变量一般先看locals()再看globals(),所以一般情况下只传locals()即可

locals globals()相关推荐

  1. python globals locals_python locals globals

    Python有两个内置的函数,locals() 和globals(),它们提供了基于字典的访问局部和全局变量的方式. 首先,是关于名字空间的一个名词解释.是枯燥,但是很重要,所以要耐心些.Python ...

  2. python-(5-3)内置函数-zip locals globals sorted filter map

    文章目录 一. zip() 二. locals() 和 globals() 三. sorted() 四. filter() 和 map() 一. zip() 作用:将多个可迭代的内容进行合并 需求:已 ...

  3. python globals locals_Python globals()和locals()比较

    Python的两个内置函数,globals()和locals() ,它们提供了基于字典的访问局部和全局变量的方式. globals()是可写的,即,可修改该字典中的键值,可新增和删除键值对. 而loc ...

  4. python中locals函数_Python locals()函数

    # Python `locals()`函数 > 原文: [https://thepythonguru.com/python-builtin-functions/locals/](https:// ...

  5. Python基础12-常用的内置函数

    abs 取绝对值,数学上的绝对值 print(abs(-1)) all 接收一个可迭代参数.如果里面有一个False的元素,那么返回值就是False,否则返回True,类似逻辑"与" ...

  6. python常用的内置函数

    内置函数,就是Python提供的, 可以直接拿来直接用的函数. 一.数字相关 01 数据类型 bool() 描述:测试一个对象是True, 还是False.bool 是 int 的子类. 语法:cla ...

  7. 第二课.Python编程基础(一)

    基础语法 注释 #行注释 """ 块注释 """ 代码分隔符 '\' code=\ """ Python St ...

  8. python-作用域

    什么是命名空间 比如有一个学校,有10个班级,在7班和8班中都有一个叫"小王"的同学,如果在学校的广播中呼叫"小王"时,7班和8班中的这2个人就纳闷了,你是喊谁 ...

  9. python学习之路基础篇(第四篇)

    一.课程内容回顾 1.python基础 2.基本数据类型  (str|list|dict|tuple) 3.将字符串"老男人"转换成utf-8 s = "老男人" ...

最新文章

  1. 编写优秀Bug报告的艺术 ----转载自CSDN(imlogic的专栏)
  2. 清华大学王晨阳:轻量级Top-K推荐框架及相关论文介绍
  3. php获取回调url方法,php回调函数的实现方法介绍(代码)
  4. HBase原理-要弄懂的sequenceId
  5. 电子工程师,学会阅读Datasheet很重要!
  6. c++矩阵类_面向对象有限元编程|单元类
  7. C# | C#中变量(局部变量)的声明和范围
  8. 【flink】95-260-045-源码-检查点-CheckPoint
  9. BZOJ3832: [Poi2014]Rally(拓扑排序 堆)
  10. mysql 事物状态有几种_关于MySQL的二十个经典面试题
  11. 关于对接网易云即时通信IM的心得
  12. 数据结构与算法分析:算法分析
  13. 学习asp.netcore入门视频
  14. 数据结构 实验 c/c++ 六度空间 图 图论
  15. 玩转AgileCDN(二)——运维小哥做报表,不再为时区换算而烦恼
  16. linux pppd ip up 脚本,pppd拨号脚本配置
  17. java 不同包 调用_java中不同包之间的调用
  18. JavaEE架构之传统三层架构,集群架构,分布式架构,微服务架构
  19. bind 跟服务器修改,DNS服务(bind9)配置过程
  20. SUMO/检测器设置(E3)学习总结

热门文章

  1. 华盛顿邮报:中国3G之争令西方手机商急上心头
  2. 【持续集成】CI工具汇总
  3. 当房奴这么痛苦,为什么很多年轻人还贷款买房?
  4. [算法]猫扑素数的算法实现
  5. JS实现鼠标滑入出现弹窗功能
  6. 高一下册计算机教案,高一下册物理下册教案设计
  7. 第17条:实现description方法
  8. 机器学习之数据的偏态分布和数据的标准化
  9. python idle怎么保存_冬虫夏草是冷藏还是冷冻?教你如何正确保存冬虫夏草!
  10. 一本通1602烽火传递