在Python函数中引用(而不是赋值)全局变量。坏习惯与否?

在Python函数中引用(而不是赋值)全局变量。坏习惯与否?,python,global-variables,Python,Global Variables,关于何时必须在Python中声明全局变量,以及与之相关的Python范围规则,有很多帖子。然而,无论是在互联网上还是在我参考过的教科书中,我都无法找到对上述更具体问题的令人满意的处理方法 即使是一个初学者,我也能理解将赋值给函数中的全局名称可能会带来的潜在困难,以及为什么大多数程序员建议尽量少用全局语句 然而,我早期的许多程序都包含许多函数,这些函数本身包含许多对全局变量的引用(即不要求声明全局变量)。在我看来,因为这些只是引用(即不改变变量),所以不会像分配给全局变量那样出现同样的困难 如果有

关于何时必须在Python中声明全局变量,以及与之相关的Python范围规则,有很多帖子。然而,无论是在互联网上还是在我参考过的教科书中,我都无法找到对上述更具体问题的令人满意的处理方法

即使是一个初学者,我也能理解将赋值给函数中的全局名称可能会带来的潜在困难,以及为什么大多数程序员建议尽量少用全局语句

然而,我早期的许多程序都包含许多函数,这些函数本身包含许多对全局变量的引用(即不要求声明全局变量)。在我看来,因为这些只是引用(即不改变变量),所以不会像分配给全局变量那样出现同样的困难

如果有更多经验的程序员能指导我函数中全局引用(相对于赋值)的最佳实践,我将不胜感激。我应该将这些全局引用更改为函数参数吗?
非常感谢。

如果您试图在函数内部使用全局变量,解释器将尝试在最近的范围内查找它,然后在其他可能的范围内查找。如果你的代码足够复杂,它会在许多范围和许多不同的变量之间循环,试图找到你想要的。如果您的脚本只包含一些不经常使用全局变量的函数,那么就可以了


总而言之,代码越复杂,搜索变量所花费的时间就越多

> P>如果只需要全局状态的引用,请考虑将它作为函数传递给函数,而不是依赖于通过作用域向上踢,直到达到全局值定义的一个。 假设全局状态真正只会被引用,并且永远不会发生变化,那么没有理由不在函数需要时将其作为参数传递。(如果全局值本身是一个大型数据结构,那么无论如何都应该通过引用传递它)


通常,这仍然会导致设计混乱,因为您将开始将状态参数作为参数到处传递。例如,如果一个函数调用其他函数,而该内部函数需要全局状态,那么外部函数也需要全局状态。通过让内部函数向上通过作用域来“解决”这个问题并不能真正减少任何依赖性,因为外部函数仍然需要嵌套在作用域中,最终导致找到全局变量。那么,为什么不至少为将来的代码读者做一件事,通过在函数的参数列表中命名变量来明确使用变量呢?

首先,模块级全局常量没有什么错,只要它们实际上是常量。如果
math
模块没有提供
pi
,我不会责怪您在模块顶部定义它,而不是将它作为参数传递给任何需要它的函数。建议在这些情况下将变量名大写。这是一个不应为这些变量赋值的信号

另一方面,我很少在代码中使用这样的常量。正如@prpl.mnky.dshwshr所建议的,倾向于将变量作为参数传递给使用它们的函数。如果继续传递相同的参数组合,例如:

def f1(foo, bar, baz, x):
    ...

def f2(foo, bar, baz, y):
    ...

def f3(foo, bar, baz, z):
    ...
它可能建议
f1
f2
f3
应该在一个类中,该类封装了
foo
bar
baz
的值:

class MyClass:
    def __init__(self, foo, bar, baz):
        self.foo = foo
        self.bar = bar
        self.baz = baz

    def f1(self, x):
        ...

    def f2(self, x):
            ...

    def f3(self, x):
            ...
如果你有很多(可能是相关的)函数反复使用相同的状态变量,这通常表明你真正想要的是一个类。