[解決済み] インポートモジュールにおけるグローバル変数の可視化
質問
Pythonスクリプトでモジュールをインポートする際に、ちょっとした壁にぶつかった。私は、エラー、なぜそれに遭遇するのか、そしてなぜ私の問題を解決するためにこの特定のアプローチと結びついているのかを説明するために最善を尽くします(これはすぐに説明します)。
例えば、あるモジュールでユーティリティ関数やクラスを定義し、そのクラスがこの補助モジュールがインポートされるネームスペースで定義されたエンティティを参照しているとします(quot;a"をそのようなエンティティとします)。
モジュール1:
def f():
print a
そして、メインプログラムには "a" が定義されており、そこにこれらのユーティリティをインポートしたいのです。
import module1
a=3
module1.f()
このプログラムを実行すると、以下のようなエラーが発生します。
Traceback (most recent call last):
File "Z:\Python\main.py", line 10, in <module>
module1.f()
File "Z:\Python\module1.py", line 3, in f
print a
NameError: global name 'a' is not defined
類似の質問があります で、いくつかの解決策が提案されましたが、これらは私の要件に適合するとは思えません。 ここで、私の特殊な状況を説明します。
MySQLデータベースサーバーに接続し、GUIでデータを表示・変更するPythonプログラムを作ろうとしています。きれいにするために、私は別のファイルで補助/ユーティリティのMySQL関連関数の束を定義しました。しかし、それらはすべて共通の変数を持っています。 内部 は、utilitiesモジュールで、これは カーソル オブジェクトを作成しました。 後で気づいたのですが、この カーソル オブジェクト (データベースサーバーと通信するために使用される) は、メインモジュールで定義されるべきです。 そうすれば、メインモジュールとそれにインポートされたものの両方がそのオブジェクトにアクセスできるようになります。
最終的にはこのような感じになります。
utilities_module.py です。
def utility_1(args):
code which references a variable named "cur"
def utility_n(args):
etcetera
そして、私のメインモジュール。
program.py。
import MySQLdb, Tkinter
db=MySQLdb.connect(#blahblah) ; cur=db.cursor() #cur is defined!
from utilities_module import *
そして、ユーティリティの関数を呼び出そうとすると、すぐに前述の "global name not defined" というエラーが発生するのです。
特に提案されたのは、ユーティリティ・ファイルに次のような "from program import cur" ステートメントを記述することです。
utilities_module.py。
from program import cur
#rest of function definitions
program.pyを使用します。
import Tkinter, MySQLdb
db=MySQLdb.connect(#blahblah) ; cur=db.cursor() #cur is defined!
from utilities_module import *
しかし、それはcyclic importとかで、結論から言うと、これもクラッシュします。そこで質問なのですが。
メインモジュールで定義された "cur" オブジェクトを、それにインポートされている補助関数から見えるようにするには、一体どうしたらいいのでしょうか?
お忙しいところありがとうございます。また、解決策が他に掲載されていたら大変申し訳ありません。もし、他の場所で解決策が掲載されていたら、大変申し訳ありません。
解決方法を教えてください。
Pythonのグローバルは、グローバル
モジュールに
すべてのモジュールにまたがるものではありません。(多くの人がこのことに戸惑いますが、例えばC言語では、グローバルは、明示的に
static
.)
これを解決する方法は、実際のユースケースによってさまざまです。
この道を進む前に、これは本当にグローバルである必要があるのか自問してみてください。もしかしたら、本当にクラスが必要かもしれません。
f
をインスタンスメソッドとして、単なるフリー関数としてではなく、?そうすると、次のようなことができる。
import module1
thingy1 = module1.Thingy(a=3)
thingy1.f()
本当にグローバルが欲しいが、それは単に
module1
そのモジュールに設定してください。
import module1
module1.a=3
module1.f()
一方、もし
a
が多くのモジュールで共有されている場合、それを別の場所に置き、全員がそれをインポートするようにします。
import shared_stuff
import module1
shared_stuff.a = 3
module1.f()
... そして、module1.pyで。
import shared_stuff
def f():
print shared_stuff.a
ドンマイ
を使用します。
from
インポートは、その変数が定数であることを意図している場合を除きます。
from shared_stuff import a
を使用すると、新しい
a
変数に初期化された
shared_stuff.a
はインポート時に参照したものであり、この新しい
a
への代入の影響を受けません。
shared_stuff.a
.
あるいは、本当にビルトインのようにどこでもグローバルであることが必要な場合は、ビルトインモジュールに追加してください。Python 2.xと3.xで正確な詳細は異なりますが、3.xではこのように動作します。
import builtins
import module1
builtins.a = 3
module1.f()
関連
-
Python入門 openを使ったファイルの読み書きの方法
-
[解決済み】Django: ImproperlyConfigured: SECRET_KEY 設定は空であってはならない
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み] 関数内でグローバル変数を使用する
-
[解決済み] Pythonで静的なクラス変数は可能ですか?
-
[解決済み] 億の相対的輸入
-
[解決済み] ローカルにインストールされたPythonモジュールの一覧を取得するにはどうしたらいいですか?
-
[解決済み] 親フォルダからモジュールをインポートする
-
[解決済み] Pythonモジュールのバージョンを確認する方法は?
-
[解決済み] モジュール名を文字列で指定してインポートするには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
PythonによるLeNetネットワークモデルの学習と予測
-
Pythonコンテナのための組み込み汎用関数操作
-
ピローによる動的キャプチャ認識のためのPythonサンプルコード
-
pythonサイクルタスクスケジューリングツール スケジュール詳解
-
Python百行で韓服サークルの画像クロールを実現する
-
PythonでECDSAを実装する方法 知っていますか?
-
[解決済み】OSError: [WinError 193] %1 は有効な Win32 アプリケーションではありません。
-
[解決済み】ImportError: PILという名前のモジュールがない
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み】LogisticRegression: Pythonでsklearnを使用して、未知のラベルタイプ: '連続'を使用しています。