2011-01-07 1243 views
10

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

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

+5

当然,你知道,全局变量eeeevil?在可能的情况下,不要编写依赖于参数以外的任何函数。除非在非常罕见的情况下,否则从来不会从一个以上的角度修改全局。这几乎没有必要,并且很容易在以后增加令人头疼的问题。总之,不值得。 – delnan 2011-01-07 21:46:07

回答

22

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

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

and expect 1。相反,你需要做的声明,你打算使用global x

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

但要注意的一个变量的分配对象是从方法调用非常不同。你可以随时调用任何范围内的方法 - 例如对来自外部(例如全局)范围的变量,因为没有局部影响它们。

而且非常重要:成员分配(x.name = ...),项目分配(collection[key] = ...),切片分配(sliceable[start:end] = ...)和propably更是所有方法调用的!因此,您不需要global来更改全局成员或调用它的方法(即使它们改变对象时)。

4

是的,如果要写入它,则需要使用global foo

foo = [] 

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

虽然没有严重错误(在这个例子中,`global`是必须的),这是误导性的。对于初学者来说,很多人似乎不同意Python对“写入”的概念。 – delnan 2011-01-07 21:43:30

+0

谢谢,这是否也适用于字典? – Hossein 2011-01-07 21:45:13

+2

@Hossein:对于任何变量都是一样的。引用的对象并不重要。 – delnan 2011-01-07 21:49:02

1

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

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

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

在文件foomodule.py:

alist = [] 

在文件barmodule.py:

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