如何在 Python 函数中创建全局变量2024 年 8 月 29 日 | 阅读 11 分钟 在本教程中,我们将学习如何在 Python 函数中创建全局变量。全局变量是一种可以在程序任何部分(包括函数内部)访问的变量。为确保代码的正确运行,区分访问和修改目标全局变量的值非常重要。 全局变量在软件开发中扮演着重要的角色,因为它们确保了整个平台的数据共享。 在 Python 函数中使用全局变量我们可以在程序的任何级别访问和修改全局变量。在 Python 中,全局变量在模块级别定义。使用全局变量时,在模块和函数中访问和修改它们可能会引起一些混淆。虽然全局变量可以在模块本身或其他模块中使用,但由于访问和修改全局变量的方式不同,在函数中处理它们需要仔细考虑。 当函数访问全局变量时,Python 会检查各种作用域中的变量。
在 Python 中访问内部函数中的变量时,解释器遵循特定的搜索模式。它首先在函数内部查找变量。如果未找到变量,则继续在外部函数的封闭作用域中搜索。如果变量仍未定义,Python 然后按此顺序在全局作用域和内置作用域中搜索。如果找到变量,则返回其值。但是,如果未在任何这些作用域中找到变量,则会引发 NameError。 让我们理解下面的例子。 示例 -在上面的示例中,我们在 outer_function() 内部定义了 inner_function()。inner_function() 拥有的代码块代表局部作用域,而 outer_function() 代码块代表非局部作用域。如果我们调用 outer_function() 而不声明 some_variable,它将引发 NameError 异常。 如果我们将 some_variable 定义为全局变量,那么我们将得到类似 Hello I am in global scope. 的输出。默认情况下,Python 解释器在局部、非局部和全局作用域中搜索 some_variable。我们可以在任何作用域中定义此变量,Python 将找到它并打印其内容。 这种搜索机制允许在函数内部使用全局变量。但它也有一个缺点。例如 - 我们可以轻松访问变量,但不能修改变量。 示例 - 输出 50 50 access_number() 函数运行良好,并在全局作用域中找到 num。另一方面,modify_number() 未按定义工作。因为我们无法从较高级别作用域(全局)修改变量到较低级别作用域(局部)。 Python 内部假设在函数内部直接赋值的任何名称都被视为该特定函数的局部变量。这意味着如果函数内部有一个名为“num”的变量被赋值,它将优先于同名的全局变量。换句话说,局部名称“num”会遮蔽或隐藏同名的全局变量。 在这种情况下,全局变量可以被视为只读名称。虽然我们可以访问全局变量的值,但不能直接修改它们。 当我们尝试在函数内部修改全局变量时,我们可能会遇到另一个异常,例如 UnboundLocalError。让我们理解以下示例。 示例 -当我们运行上述代码时,我们首先得到 a、b 和 c 的值。然后在函数内部,我们直接修改 c。预期输出如下: print(get_globals()) 10 20 30 100 但是,我们不会得到此输出;相反,我们会得到以下异常。 print(get_globals()) Traceback (most recent call last): File "<string>", line 10, in <module> File "<string>", line 6, in get_globals UnboundLocalError: cannot access local variable 'c' where it is not associated with a value 问题在于赋值 c = 100 创建了一个新的局部变量,该变量优先于原始全局变量 c。这导致两个同名变量之间发生冲突。该异常,特别是 UnboundLocalError,是由第一次调用 print() 触发的,因为在那一刻,c 的局部版本尚未定义。 此问题发生在对全局变量的增强赋值操作中。 输出 Traceback (most recent call last): File " 在 Python 中,如果函数引用了来自全局作用域的变量,则函数假定该变量是全局变量。如果在函数体中定义了变量名,则表示我们正在定义一个与原始全局变量同名的新局部变量。如果我们在函数中定义了同名的局部变量,则在函数内部无法直接访问全局变量。 如果您打算在函数内部修改全局变量,则需要明确指示 Python 使用全局变量而不是创建新的局部变量。Python 提供以下方法来实现:
global 关键字早些时候,我们讨论了如何在函数内部直接访问全局变量(如果局部变量与全局变量同名)。但在某些情况下,我们需要更改全局变量的值。在这种情况下,我们可以使用 global 关键字声明我们想要引用全局变量。 以下是 global 语句的语法。 为了理解此语句,我们正在使用计数器和增量示例。我们可以使用 global 关键字修复代码。 示例 - 输出 1 1 2 2 在 increment() 函数的更新版本中,使用 global 关键字明确表示目的是修改全局变量 counter。通过包含此语句,函数现在能够在其作用域内更改 counter 变量的值。 如果我们在 global 声明之前使用目标变量,我们将得到一个 SyntaxError。 输出 File " 总而言之,当您打算在函数内部重新赋值或修改全局变量的值时,global 关键字是必需的。但是,如果您的目标只是在函数内部读取或访问全局变量的值,则不需要 global 关键字。 为了处理函数内部的全局变量,我们还可以使用内置的 globals() 函数。 globals() 函数globals() 函数是 Python 中的一个内置函数,它提供对全局作用域名称表的访问。该名称表是一个字典,其中包含当前全局名称及其各自的值。通过利用此函数,您可以在函数内部访问和修改全局变量的值。 globals() 函数在以下情况下特别有用:您有与所需全局变量同名的局部变量,并且您仍然需要在函数内部访问或修改全局变量。通过利用 globals() 函数,您可以明确引用全局变量并将其与同名的局部变量区分开来,从而允许您在函数内部使用预期的全局变量。 示例 - 输出 10 20 30 100 30 在 print_globals() 的修订实现中,变量“c”引用了变量的局部版本,而 globals()["c"] 引用了全局版本。 通过利用返回字典的 globals() 函数,您可以像使用任何常规字典一样访问其键。重要的是要注意,要访问 globals() 字典中的特定键,您需要使用变量的名称作为字符串。 globals() 返回的字典是可变的,允许您通过利用此字典修改现有全局变量的值。在最后一个示例中,很明显,尽管通过 globals() 字典对其进行了修改,全局变量“c”仍保留其原始值。 示例 - 输出 1 2 在这个特定示例中,increment() 函数已使用 globals() 函数而不是 global 关键字实现。两种实现都达到了相同的结果,这由连续函数调用后计数器变量的一致值所证明。 但是,重要的是要注意,使用 globals() 访问和更新全局变量可能会使您的代码可读性降低且更难理解,尤其是在大型程序中。通常,建议使用 global 关键字,除非您特别遇到局部变量与预期全局变量同名的情况。 在函数内部创建全局变量正如我们之前发现的,global 关键字和内置的 globals() 函数都可用于在函数内部访问和修改全局变量。然而,可能特别有趣和令人惊讶的是,我们还可以使用这些工具在函数内部创建全局变量。 让我们理解下面的例子。 示例 - 输出 100 100 在给定示例中,函数 set_global_variable() 利用 global 关键字将“number”声明为全局变量。调用函数时,“number”被定义为全局变量并赋值为 100。函数调用后,“number”可以从程序的任何其他部分访问。 在函数内部定义新的全局变量的另一个选项是利用 globals() 函数。这种方法提供了额外的灵活性,使我们能够动态创建全局变量。通过利用 globals() 函数,您可以在函数内部动态引入新的全局变量。 示例 - 输出 100 100 让我们举一个真实的例子,假设我们有一个 JSON 格式的配置文件。我们需要处理该文件并将所有配置参数直接加载到全局命名空间中,以便这些参数可以在代码的其他部分中使用。 config.json 文件可能如下所示。 在该文件中,database 是一个键,它包含另一个键值字典。此文件包含数据库的基本设置,还定义了 API 密钥、基本 URL 和连接到 API 的超时。 使用以下代码,我们可以加载 JSON 文件并创建所需的全局变量集。 示例 - 输出 { 'host': 'localhost', 'port': 5432, 'name': 'database.db', 'user': 'username', 'password': 'secret' } '000111222333' 'https://example.com/api' 60 以上代码定义了 set_config_key(),它将键和值作为参数。我们使用 globals() 来创建一个全局变量,其中键作为变量名,值作为其值。 with 语句用于打开配置;我们读取文件并将文件对象分配给 config_keys 变量。for 循环处理加载的配置并为每个键值对创建新的全局变量。 何时使用全局变量在项目工作中,我们会遇到一些需要使用全局变量的情况。这些场景可能涉及在不同模块之间共享数据或状态、促进系统各种组件之间的通信或维护集中式配置或设置存储库。以下是一些必须使用全局变量的情况。
此外,全局变量有一些缺点,如下所示。
结论在您探索 Python 函数中全局变量的使用过程中,您获得了宝贵的见解。显然,直接在函数内部访问全局变量是可行的,但修改它们需要使用 global 关键字或 globals() 函数。 全局变量用于在多个函数之间共享数据,在某些情况下提供便利。但是,在使用此类变量时,务必谨慎和克制。过度使用全局变量会导致代码复杂、难以理解、调试、测试和维护。建议明智地使用全局变量,考虑潜在的缺点,并力求使代码更具可读性、模块化且易于维护。 |
我们请求您订阅我们的新闻通讯以获取最新更新。