无法在 Python 中导入全局变量 [重复]

Posted

技术标签:

【中文标题】无法在 Python 中导入全局变量 [重复]【英文标题】:Unable to import global variables in Python [duplicate] 【发布时间】:2018-03-11 23:12:10 【问题描述】:

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

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 中的x += 99 行收到错误NameError: name 'x' is not defined

更改导入语句以包含 x (from inner_foo import inner_foo, x) 给我们:

ImportError: cannot import name 'x'

【问题讨论】:

请先更正您的格式。 你的函数体没有缩进。全局变量后不需要分号。 【参考方案1】:

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

def f():
    global x
    x += 1

a 中没有x,只有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

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

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

有效!所以说得尽量简洁:

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

但是!

既然您已经掌握了这些知识,请不要走这条设计道路。依赖于跨模块改变全局状态是一条悲伤的道路。不要这样做,不建议这样做,因为几代编码人员发现这很糟糕。重新设计您的方法,您将构建更强大、更易于推理且错误更少的软件。

【讨论】:

以上是关于无法在 Python 中导入全局变量 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Node 中导入全局模块?我得到“错误:找不到模块 <module>”?

如何使用 PostCSS 在 Vue 中导入全局 CSS?

在 Angular 中导入全局 css 文件会导致 Webpack 发出巨大的模块包

如何在全局中导入 lib,以便可以在导入的 js 文件中访问它?

如何使 sass 文件全局化,而不是在每个文件中导入它并膨胀包大小?

在 Python 中导入 Tkinter 时出现 ImportError [重复]