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

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

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

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

I want to define a constant that should be available in all of the submodules of a package. I’ve thought that the best place would be in in the __init__.py file of the root package. But I don’t know how to do this. Suppose I have a few subpackages and each with several modules. How can I access that variable from these modules?

Of course, if this is totally wrong, and there is a better alternative, I’d like to know it.


回答 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

You should be able to put them in __init__.py. This is done all the time.

mypackage/__init__.py:

MY_CONSTANT = 42

mypackage/mymodule.py:

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

Then, import mymodule:

>>> from mypackage import mymodule
my constant is 42

Still, if you do have constants, it would be reasonable (best practices, probably) to put them in a separate module (constants.py, config.py, …) and then if you want them in the package namespace, import them.

mypackage/__init__.py:

from mypackage.constants import *

Still, this doesn’t automatically include the constants in the namespaces of the package modules. Each of the modules in the package will still have to import constants explicitly either from mypackage or from mypackage.constants.


回答 1

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

# mypackage/config.py
MY_CONST = 17

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

You cannot do that. You will have to explicitely import your constants into each individual module’s namespace. The best way to achieve this is to define your constants in a “config” module and import it everywhere you require it:

# mypackage/config.py
MY_CONST = 17

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

回答 2

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

而且我想没人会推荐这种做法。命名空间有什么问题?说应用程序版本模块,这样我可以有像“全局”变量version.VERSIONversion.PACKAGE_NAME等等。

You can define global variables from anywhere, but it is a really bad idea. import the __builtin__ module and modify or add attributes to this modules, and suddenly you have new builtin constants or functions. In fact, when my application installs gettext, I get the _() function in all my modules, without importing anything. So this is possible, but of course only for Application-type projects, not for reusable packages or modules.

And I guess no one would recommend this practice anyway. What’s wrong with a namespace? Said application has the version module, so that I have “global” variables available like version.VERSION, version.PACKAGE_NAME etc.


回答 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

Just wanted to add that constants can be employed using a config.ini file and parsed in the script using the configparser library. This way you could have constants for multiple circumstances. For instance if you had parameter constants for two separate url requests just label them like so:

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

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

I found the documentation on the Python website very helpful. I am not sure if there are any differences between Python 2 and 3 so here are the links to both:

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

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