返回介绍

global 语句

发布于 2024-01-29 22:24:16 字数 2360 浏览 0 评论 0 收藏 0

global语句是Python中唯一看起来有些像声明语句的语句。但是,它并不是一个类型或大小的声明,它是一个命名空间的声明。它告诉Python函数打算生成一个或多个全局变量名。也就是说,存在于整个模块内部作用域(命名空间)的变量名。

我们已经在前边讲过了全局变量名。这里只是作一个总结。

·全局变量是位于模块文件内部的顶层的变量名。

·全局变量如果是在函数内被赋值的话,必须经过声明。

·全局变量名在函数的内部不经过声明也可以被引用。

换句话说,global允许我们修改一个模块文件的顶层的一个def之外的名称。正如我们将在随后看到的,nonlocal语句几乎是相同的,但它应用于嵌套的def的本地作用域内的名称,而不是嵌套的模块中的名称。

global语句包含了关键字global,其后跟着一个或多个由逗号分开的变量名。当在函数主体被赋值或引用时,所有列出来的变量名将被映射到整个模块的作用域内。例如:

这个例子中我们增加了一个global声明,以便在def之内的X能够引用在def之外的X,这次它们有相同的值。这里有一个global使用的例子:

这里,x、y和z都是all_global函数内的全局变量。y和z是全局变量,因为它们不是在函数内赋值的;x是全局变量,因为它通过global语句使自己明确地映射到了模块的作用域。如果不使用global语句的话,x将会由于赋值而被认为是本地变量。

注意:y和z并没有进行global声明。Python的LEGB查找法则将会自动从模块中找到它们。此外,注意x在函数运行前可能并不存在。如果这样的话,函数内的赋值语句将自动在模块中创建x这个变量。

最小化全局变量

在默认情况下,函数内部注册的变量名是本地变量,所以如果希望在函数外部对变量进行改变,必须编写额外的代码(global语句)。这是有意而为的。这似乎已成为Python中的一种惯例,如果想做些“错误”的事情,就得多编写代码。尽管有些时候global语句是有用的,然而在def内部赋值的变量名默认为本地变量,通常这都是最好的约定。将其改为全局变量会引发一些软件工程问题:由于变量的值取决于函数调用的顺序,而函数自身是任意顺序进行排列的,导致了程序调试起来变得很困难。

作为例子,思考一下这个模块文件。

现在,假设你的任务就是修改或重用这个模块文件。这里X的值将会是什么?确切地说,如果不确定引用的时间,这个问题就是毫无意义的。X的值与时间相关联,因为它的值取决于哪个函数是最后进行调用的(有时我们是无法单从这个文件就能说明白的)。

实际的结果就是,为了理解这个代码,你必须去跟踪整个程序的控制流程。此外,如果重用或修改了代码,你必须随时记住整个程序。在这种情况下,如果使用这两个函数中的一个的话,必须要确保没有在使用另一个函数。它们通过全局变量而变得具有相关性(也就是说,是耦合在一起的)。这就是使用全局变量的问题:不像那些依赖于本地变量的由自包含的函数构成的代码,全局变量使得程序更难理解和使用。

另一方面,不使用面向对象的编程方法以及类的话,全局变量也许就是Python中最直接保持状态信息的方法(函数在其下次被调用时需要记住的信息):本地变量在函数返回时将会消失,而全局变量不是这样。另一种技术,例如,默认可变参数以及嵌套函数作用域,也能够实现这一点,但是它们与将值推向全局作用域来记忆这种方法相比过于复杂了。

一些程序委任一个单个的模块文件去定义所有的全局变量。只要这样考虑,那么就没有什么不利的因素了。此外,在Python中使用多线程进行并行计算程序实际上是要依靠全局变量的。因为全局变量在并行线程中在不同的函数之间成为了共享内存,所以扮演了通信工具的角色。[1]

到目前为止,在不熟悉编程的情况下,最好尽可能地避免使用全局变量(试试通过传递函数然后返回值来替代一下)。六个月以后,你和你的合作者都会感谢你没有使用那么多全局变量。

[1]多线程与其他的程序并行地运行函数调用,并且得到Python的标准库模块_thread、threading和queue(在Python 2.6中分别是thread、threading和Queue)的支持。由于所有这些线程化函数都在同一进程中运行,全局作用域往往充当它们之间的共享内存。线程用于GUI中长时间运行的任务,以实现广泛地实现非阻塞的操作并利用CPU的能力。这也超出了本书的讨论范围,参见Python库手册和前言中列出的相关图书(例如O'Reilly的Programming Python),可以了解更多细节。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文