Python globals() locals() vars() 三个内建函数的区别

在阅读模块源码里, 常常看到 globals() locals() 的使用, 这两个函数虽然可以从命名中
从外观上知道不同, 但仍然不明白具体使用方式和实际的意义. 带着好奇和疑问, 先看看
文档和搜索相关的博客, 额外还了解到vars() 函数的信息, 在此带着样例代码介绍.

首先参考官方文档对这三个函数的介绍:

2. Built-in Functions – Python3.5
globals()
返回当前全局符号表, 通常在是返回当前模块下的全局符号表, 比如全局内建的函数,
以及模块里的全局符号(定义声明的变量,类, 实例等), 在函数或者类方法中, globals()
返回的模块符号表是其所在模块, 而不是调用模块.

locals() 更新并以字典形式返回当前局部符号表. 自由变量由函数块的locals() 返回, 而
不会由 class 块来返回. 需要注意的是, locals() 字典不应该被修改; 在解释器中对修改行为
可能对 local 值或者自由变量无效.

vars() 返回 __dict__ 属性, 比如模块, 类, 实例, 或者其他 带有 __dict__ 属性的 object.
比如 模块和实例拥有可更新的 __dict__ 属性;然而其他 objects 可能会对 __dict__ 属性
的写操作限制(例如 类使用 dictproxy 阻止直接对字典更新).
vars() 如果不传参数, 那么作用与 locals() 一样. 需要注意的是, locals 字典只在读操作
时使用, 因为对 locals 的更新会被忽略.

翻译完相关文档解释后, 用代码实验:

通过代码验证, 反过来理解文档的解释. 也明白了之前阅读他人代码使用的目的.
有另外一人写的文章 Python Does What?!? 介绍了 dict 和 vars 的使用.
文中引用一篇推特吐槽, 原文是:

Most folks prefer len(s) to s.__len__(), prefer next(it) to it.next(),
but forget to use vars(s) rather than s.__dict__

只能说明 vars 这个函数的命名并不是那么直观, 而且已经有了 dict() 的定义, 也许
设计者想出个 vars 命名来使用 233.

其他细节:
* 另外值得一提的是, 直接访问实例 __dict__ 或者其他属性, 比用内建函数访问更高效.
* 在模块里的全局作用域, 调试时会观察到 gloabls() (以及等价的 locals())里的 key
是动态变化的. 那么随着赋值给新变量名后, 字典会动态增加对应的 key.

原创文章,转载请注明: 转载自kaka_ace's blog

本文链接地址: Python globals() locals() vars() 三个内建函数的区别

发表评论

电子邮件地址不会被公开。 必填项已用*标注