Python:如何访问调用模块中的变量?

Python:如何访问调用模块中的变量?,python,Python,假设我有一个主模块app.py,它定义了一个全局变量GLOBVAR=123。此外,此模块还导入位于另一个模块中的类条: from foo import bar 在主模块app中,我现在从类bar调用一个方法。在该方法中,我希望从主模块app访问值GLOBVAR 一种简单的方法是将GLOBVAR作为参数传递给方法。但是Python中是否还有另一种解决方案允许我直接访问GLOBVAR 在模块foo中,我尝试了以下方法之一: from app import GLOBVAR # option 1 i

假设我有一个主模块
app.py
,它定义了一个全局变量
GLOBVAR=123
。此外,此模块还导入位于另一个模块中的类

from foo import bar
在主模块
app
中,我现在从类
bar
调用一个方法。在该方法中,我希望从主模块
app
访问值
GLOBVAR

一种简单的方法是将
GLOBVAR
作为参数传递给方法。但是Python中是否还有另一种解决方案允许我直接访问
GLOBVAR

在模块
foo
中,我尝试了以下方法之一:

from app import GLOBVAR  # option 1
import app.GLOBVAR       # option 2
但是,这两个选项在运行时都会导致以下错误:

ImportError: cannot import name bar

我知道这会导致
app
foo
之间的循环导入。那么,Python中是否有解决方案,或者我是否必须将值作为参数传递给函数?

您应该在要使用GLOBVAR的位置之前写入导入行,这将防止循环

在foo.py中,行

from app import GLOBVAR

必须在
类定义之后。

您可以将GLOBVAR放入第三个模块,将其导入
foo
,并在
app
内部从
foo
导入

glob.py:

GLOBVAR=None
foo.py:

class bar:
    global GLOBVAR
    from glob.py import GLOBVAR
app.py:

 from foo import GLOBVAR
 import foo

解决同一问题的方法有很多,通常建议使用传递参数。但是,如果您确实有一些包范围的全局常量,您也可以这样做。您需要将这些模块放入另一个模块中,并从
app
foo
模块导入该模块。如果您构建了一个包globals,您甚至可以将它们放在
\uuuu init\uuuu.py
中。。。但也可以使用另一个命名模块,如
settings
config

例如,如果包布局为:

mypackage/
    __init__.py
    app.py
    foo.py
    config.py
然后:

config.py

GLOBVAR = 'something'
app.py

from mypackage.config import GLOBVAR
福比

from mypackage.config import GLOBVAR
如果您只是将GLOBVAR放入
\uuu init\uuu.py
中,那么您可以从mypackage import GLOBVAR中执行
,如果您选择这种方式,它可能会更漂亮


编辑我还建议使用绝对导入,即使您使用的是python 2,为了可读性,请始终明确使用包名,而不是相对导入,因为如果您需要将某个包移动到另一个新的包中,这会使以后更容易拆分,因此您可以从
\uuuu main\uuuu
模块中导入变量,如下所示:

""" main module """
import foo
name = "Joe"
foo.say_hi()
$ python main.py
Hi, Joe!
foo.py

""" foo module, to be imported from __main__ """
import __main__
def say_hi():
    print "Hi, %s!" % __main__.name
看起来是这样的:

""" main module """
import foo
name = "Joe"
foo.say_hi()
$ python main.py
Hi, Joe!

当然,在定义变量之前不能访问它。因此,您可能需要将对
\uuuuu main\uuuu.name
的访问权置于函数级别,在导入后对其进行评估。与模块级别相反,模块级别在导入时进行评估(变量尚未存在)。

这就是为什么全局变量是Evil@Ant当前位置是的,我同意全球化通常不是一条发展之路。然而,我也认为在某些情况下它们是可以的,特别是对于原型。但我认为这将是另一个话题的讨论:)谢谢,这是对我问题的一个非常有用的回答。尽管正如雅利安所建议的那样,在我在方法中使用GLOBVAR之前直接导入
GLOBVAR
,我还是接受你的答案,因为它看起来更优雅。