假设我有一个主模块app.py
,它定义了一个全局变量GLOBVAR = 123
。此外,此模块还会导入位于另一个模块bar
中的类foo
:
from foo import bar
在主模块app
中,我现在从类bar
调用一个方法。在该方法中,我想从主模块GLOBVAR
访问值app
。
一种直接的方法是简单地将GLOBVAR
作为参数传递给方法。但是,Python中还有另一个解决方案允许我直接访问GLOBVAR
吗?
在模块foo
中,我尝试了以下其中一项:
from app import GLOBVAR # option 1
import app.GLOBVAR # option 2
但是,这两个选项在运行时都会导致以下错误:
ImportError: cannot import name bar
我了解这会导致app
和foo
之间的循环导入。那么,在Python中是否有解决方案,或者我必须将值作为参数传递给函数吗?
答案 0 :(得分:4)
有很多方法可以解决同样的问题,通常建议传递参数。但是,如果你确实有一些包广泛的全局常量,你也可以这样做。您将希望将它们放在一个完整的其他模块中,并从app
和foo
模块中导入该模块。如果您构建一个包全局变量,您甚至可以将它们放在__init__.py
...中,但也可以使用另一个命名模块,如settings
或config
。
例如,如果您打包布局是:
mypackage/
__init__.py
app.py
foo.py
config.py
然后:
config.py
GLOBVAR = 'something'
app.py
from mypackage.config import GLOBVAR
foo.py
from mypackage.config import GLOBVAR
如果您只是将GLOBVAR放在__init__.py
中,那么您可以from mypackage import GLOBVAR
,如果您选择这样的话,那会更漂亮。
编辑我还建议使用绝对导入,即使您使用的是python 2,并且为了便于阅读,请始终明确使用包名而不是相对导入,因为这样可以在以后拆分时更容易如果您需要将某些东西移到新的不同包中
答案 1 :(得分:1)
你应该在你想要使用GLOBVAR之前写下导入行,这样可以防止循环!
答案 2 :(得分:1)
在foo.py中,行
from app import GLOBVAR
必须在bar
类定义之后。
答案 3 :(得分:1)
您可以将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
答案 4 :(得分:0)
您可以从__main__
模块导入变量,如下所示:
""" main module """
import foo
name = "Joe"
foo.say_hi()
和foo.py
:
""" foo module, to be imported from __main__ """
import __main__
def say_hi():
print "Hi, %s!" % __main__.name
它看起来像这样:
$ python main.py
Hi, Joe!
当然,在定义变量之前,您无法访问该变量。因此,您可能需要在功能级别对__main__.name
进行访问,在导入后对其进行评估。与模块级别相反,模块级别在导入时评估(变量尚不存在)。