无法在Python中导入全局变量

时间:2017-09-30 02:50:49

标签: python python-3.x global-variables global python-import

以下所有内容都在一个文件中:

def inner_foo(in_arg):
    global x;
    x += 99
    return in_arg + 1

def outer_foo(in_arg):
    global x;
    x = 0
    output = inner_foo(in_arg)
    return output    

result = outer_foo(5)
print("result == ", result)
print("x == ", x)

当它在一个文件中时,它可以正常工作。以下是打印的内容:

result ==  6
x ==  99

但是,如果我们尝试将程序拆分为多个文件,我们就会遇到问题。

# CONTENTS OF inner_foo.py
def inner_foo(in_arg):
global x;
x += 99
return in_arg + 1

这是另一个文件:

# CONTENTS OF outer_foo.py
from inner_foo import inner_foo
def outer_foo(in_arg):
    global x
    x = 0
    output = inner_foo(in_arg)
    return output

result = outer_foo(5)
print("result == ", result)
print("x == ", x)

我们在inner_foo.py

内的NameError: name 'x' is not defined行上收到错误x += 99

将import语句更改为包含x(from inner_foo import inner_foo, x)会给我们:

ImportError: cannot import name 'x'

1 个答案:

答案 0 :(得分:0)

Python“全局”范围实际上是模块级,正如您在尝试导入时推断的那样。问题是,当您执行x += 1时,这相当于x = x + 1,但 x 从未在您的模块中定义过。所以,假设我们有a.py

def f():
    global x
    x += 1

x没有a,只有f现在,让我们打开一个REPL:

>>> import a
>>> a.f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/juan/workspace/temp/globals_modules/a.py", line 3, in f
    x += 1
NameError: name 'x' is not defined

并且,如上所述,“全局范围”实际上是模块级范围,因此f的全局范围是模块a的命名空间,不一定是调用者的全局范围,即:

>>> x = 0
>>> a.f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/juan/workspace/temp/globals_modules/a.py", line 3, in f
    x += 1
NameError: name 'x' is not defined

所以,实际上,它正在x的命名空间中查找a,所以如果我们执行以下操作:

>>> a.x = 0
>>> a.f()
>>> a.x
1
>>> a.f()
>>> a.x
2

有效!所以尽可能简洁地说:

>>> a.f.__globals__ is globals()
False

然而!

现在你掌握了这些知识,沿着这条设计路径前进。依靠模块之间不断变化的全局状态是一条悲伤的道路。不要这样做,不建议这样做,因为几代编码器发现这很糟糕。重新设计您的方法,您将构建更强大,更容易推理和减少错误的软件。