web-dev-qa-db-ja.com

__init__.pyを使用してグローバル変数を定義できますか?

パッケージのすべてのサブモジュールで使用できる定数を定義したい。最適な場所は、ルートパッケージの__init__.pyファイルにあると考えました。しかし、私はこれを行う方法がわかりません。いくつかのサブパッケージがあり、それぞれにいくつかのモジュールがあるとします。これらのモジュールからその変数にアクセスするにはどうすればよいですか?

もちろん、これが完全に間違っていて、より良い代替案があれば、私はそれを知りたいです。

107
Andrei Vajna II

それらを__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から定数を明示的にインポートする必要があります。

172
Jason R. Coombs

それをしてはいけない。個々のモジュールの名前空間に定数を明示的にインポートする必要があります。これを実現する最良の方法は、「c​​onfig」モジュールで定数を定義し、必要な場所にインポートすることです。

# mypackage/config.py
MY_CONST = 17

# mypackage/main.py
from mypackage.config import *
30
Ferdinand Beyer

どこからでもグローバル変数を定義できますが、それは本当に悪い考えです。 __builtin__モジュールをインポートし、このモジュールに属性を変更または追加すると、突然新しい組み込み定数または関数が作成されます。実際、私のアプリケーションがgettextをインストールすると、何もインポートせずに、すべてのモジュールで_()関数を取得します。したがって、これは可能ですが、もちろん、再利用可能なパッケージまたはモジュールではなく、アプリケーションタイプのプロジェクトに対してのみです。

とにかく、誰もこの練習を勧めないでしょう。名前空間の何が問題になっていますか?このアプリケーションにはバージョンモジュールがあるため、version.VERSIONversion.PACKAGE_NAMEなどの「グローバル」変数を使用できます。

2
u0b34a0f6ae

定数を追加したかったのは、config.iniファイルを使用して定数を使用し、configparserライブラリを使用してスクリプトで解析できることです。このようにして、複数の状況で定数を使用できます。たとえば、2つの個別のURLリクエストのパラメータ定数がある場合は、次のようにラベルを付けます。

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

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

Python Webサイトのドキュメントは非常に役立ちました。 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

1
Dan Temkin