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

时间:2009-09-05 12:33:04

标签: python global-variables module packages init

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

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

4 个答案:

答案 0 :(得分:163)

您应该可以将它们放入__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明确导入常量。

答案 1 :(得分:30)

你做不到。您必须明确地将常量导入每个单独模块的命名空间。实现这一目标的最佳方法是在“config”模块中定义常量,并将其导入到您需要的任何位置:

# mypackage/config.py
MY_CONST = 17

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

答案 2 :(得分:2)

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

我想无论如何都不会推荐这种做法。命名空间有什么问题?所述应用程序具有版本模块,因此我可以使用version.VERSIONversion.PACKAGE_NAME等“全局”变量。

答案 3 :(得分:1)

只是想补充一点,可以使用config.ini文件使用常量,并使用configparser库在脚本中解析。这样你可以有多种情况的常量。例如,如果您有两个单独的url请求的参数常量,则只需将它们标记为:

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

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

我发现Python网站上的文档非常有用。我不确定Python 2和3之间是否存在任何差异,因此以下是两者的链接:

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

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