我可以使用 _ _ init _ _. py 来定义全局变量吗?

我想定义一个常量,它应该可以在包的所有子模块中使用。我认为最好的位置是在根包的 __init__.py文件中。但我不知道该怎么做。假设我有几个子包,每个子包都有几个模块。如何从这些模块访问该变量?

当然,如果这是完全错误的,有更好的选择,我想知道它。

120032 次浏览

你不能这么做。您必须显式地将常量导入到每个模块的名称空间中。实现这一点的最佳方法是在“ config”模块中定义常量,并在需要的任何地方导入它:

# mypackage/config.py
MY_CONST = 17


# mypackage/main.py
from mypackage.config import *

你应该能够把他们在 __init__.py。这是所有的时间。

mypackage/__init__.py :

MY_CONSTANT = 42

mypackage/mymodule.py :

from mypackage import MY_CONSTANT
print "my constant is", MY_CONSTANT

然后,导入 mymodule:

>>> from mypackage import mymodule
my constant is 42

尽管如此,如果您确实有常量,那么将它们放在一个单独的模块(Constants.py,config.py,...)中是合理的(可能是最佳实践) ,然后如果您希望将它们放在包名称空间中,那么导入它们。

mypackage/__init__.py :

from mypackage.constants import *

不过,这并不会自动包含包模块的名称空间中的常量。包中的每个模块仍然必须显式地从 mypackagemypackage.constants导入常量。

您可以在任何地方定义全局变量,但这是一个非常糟糕的主意。导入 __builtin__模块并修改或添加这些模块的属性,突然您就有了新的内置常量或函数。实际上,当我的应用程序安装 gettext 时,我会在所有模块中获得 _ ()函数,而不需要导入任何内容。因此,这是可能的,但当然只适用于应用程序类型的项目,而不适用于可重用的包或模块。

我想反正也没人会推荐这种做法。名称空间有什么问题?该应用程序有版本模块,所以我有“全局”变量可用,如 version.VERSIONversion.PACKAGE_NAME等。

只是想补充一点,常量可以使用 config.ini 文件,并在脚本中使用 configparser 库进行解析。这样就可以在多种情况下使用常量。例如,如果有两个不同的 url 请求的参数常量,只需要像下面这样标记它们:

mymodule/config.ini
[request0]
conn = 'admin@localhost'
pass = 'admin'
...


[request1]
conn = 'barney@localhost'
pass = 'dinosaur'
...

我发现 Python 网站上的文档非常有用。我不确定 Python2和 Python3之间是否有任何区别,所以这里有两者的链接:

对于 Python 3: https://docs.python.org/3/library/configparser.html#module-configparser

对于 Python 2: https://docs.python.org/2/library/configparser.html#module-configparser