【问题标题】:Defining lists as global variables in Python在 Python 中将列表定义为全局变量
【发布时间】:2011-01-07 21:37:14
【问题描述】:

我正在使用一个列表,其中一些函数在我的程序中起作用。这实际上是一个共享列表,我的所有功能都可以编辑它。真的有必要在所有函数中都定义为“全局”吗?

我的意思是把 global 关键字放在每个使用它的函数中,或者在所有函数之外定义它就足够了,而不在其定义后面使用 global 词?

【问题讨论】:

  • 你当然知道全局变量是eeeevil?如果可能,不要编写依赖于参数以外的任何内容的函数。除非在非常罕见的情况下,否则永远不要从不止一个点修改全局内容。这几乎从来没有必要,而且很容易在以后增加巨大的麻烦。总之,不值得。

标签: python list global-variables


【解决方案1】:

当您分配一个变量 (x = ...) 时,您是在当前范围内创建一个变量(例如,当前函数的本地变量)。如果它恰好在外部(例如全局)范围内隐藏变量,那就太糟糕了 - Python 不在乎(这是一件好事)。所以你不能这样做:

x = 0
def f():
    x = 1
f()
print x #=>0

期待1。相反,您需要声明您打算使用global x

x = 0
def f():
    global x
    x = 1
f()
print x #=>1

但请注意,变量的赋值与方法调用非常不同。您始终可以在范围内的任何内容上调用方法 - 例如来自外部(例如全局)范围的变量,因为没有任何本地影响它们。

同样非常重要:成员分配 (x.name = ...)、项目分配 (collection[key] = ...)、切片分配 (sliceable[start:end] = ...) 以及更多的方法调用!因此,您不需要global 来更改全局成员或调用它的方法(即使它们改变了对象)。

【讨论】:

  • +1。还值得注意的是,切片分配不会覆盖引用。特别是,代替x = newlist,可以使用x[:] = new_list,并且仍然不需要使用global。这当然包含在方法调用案例中,但值得明确指出。
  • @aaron:是的。扩展以明确有很多东西(包括成员分配、切片分配等)实际上是方法调用。
【解决方案2】:

是的,如果你要写信,你需要使用global foo

foo = []

def bar():
    global foo
    ...
    foo = [1]

【讨论】:

  • 虽然没有完全错误(在示例中,global 是必需的),但这是一种误导。对于初学者来说,许多人似乎不同意 Python 关于何时“写入”的概念。
  • @Hossein:任何变量都是一样的。引用的对象无关紧要。
【解决方案3】:

不,您可以将列表指定为函数的关键字参数。

alist = []
def fn(alist=alist):
    alist.append(1)
fn()
print alist    # [1]

我会说这是不好的做法。有点太hackish了。如果您真的需要使用全局可用的类似单例的数据结构,我会使用模块级变量方法,即 将“alist”放入模块中,然后在其他模块中导入该变量:

在文件 foomodule.py 中:

alist = []

在 barmodule.py 文件中:

import foomodule
def fn():
    foomodule.alist.append(1)
print foomodule.alist    # [1]

【讨论】:

  • 澄清:“全局”是总是模块级别的。无需将其放入额外的模块中(虽然有时有用或语义上更正确)。
  • 我不知道所涉及的复杂性。如果您只想修改模块级变量(即不分配全局名称),那么我编写的两个示例似乎根本不需要。请参阅 delnan 的答案以获得更好的评估。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 2018-06-06
  • 2021-03-13
  • 1970-01-01
  • 2019-09-17
  • 1970-01-01
相关资源
最近更新 更多