问题:我可以使用__init__.py定义全局变量吗?
我想定义一个常量,该常量应在包的所有子模块中可用。我以为最好的地方__init__.py
在根包的文件中。但是我不知道该怎么做。假设我有几个子包,每个子包都有几个模块。如何从这些模块访问该变量?
当然,如果这是完全错误的,并且有更好的选择,我想知道。
回答 0
您应该能够将它们放入__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
或从中显式导入常量mypackage.constants
。
回答 1
你不能这样做。您必须将常量明确地导入每个模块的命名空间中。实现此目的的最佳方法是在“ config”模块中定义常量,并将其导入所需的任何位置:
# mypackage/config.py
MY_CONST = 17
# mypackage/main.py
from mypackage.config import *
回答 2
您可以在任何地方定义全局变量,但这是一个非常糟糕的主意。导入__builtin__
模块并修改或向该模块添加属性,突然间您有了新的内置常量或函数。实际上,当我的应用程序安装gettext时,我在所有模块中都获得了_()函数,而无需导入任何内容。因此这是可能的,但当然仅适用于应用程序类型的项目,而不适用于可重用的包或模块。
而且我想没人会推荐这种做法。命名空间有什么问题?说应用程序版本模块,这样我可以有像“全局”变量version.VERSION
,version.PACKAGE_NAME
等等。
回答 3
只是想补充一点,可以使用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