162

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

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

4

4 回答 4

240

你应该可以把它们放进去__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 *

尽管如此,这并不会自动在包模块的命名空间中包含常量。包中的每个模块仍然必须从mypackage或 from显式导入常量mypackage.constants

于 2009-09-05T12:57:05.050 回答
34

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

# mypackage/config.py
MY_CONST = 17

# mypackage/main.py
from mypackage.config import *
于 2009-09-05T12:38:56.347 回答
2

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

而且我想没有人会推荐这种做法。命名空间有什么问题?所述应用程序具有版本模块,因此我有可用的“全局”变量version.VERSION,例如version.PACKAGE_NAME等。

于 2009-09-05T15:09:14.623 回答
0

只是想补充一点,可以使用 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

于 2016-07-08T21:41:23.437 回答