Pythonスクリプトでモジュールをインポートする壁に少し遭遇しました。私はエラーを説明するために最善を尽くし、なぜそれに遭遇するのか、なぜこの特定のアプローチを結んで問題を解決するのか(これについては後で説明します):
この補助モジュールがインポートされる名前空間で定義されたエンティティを参照するユーティリティ関数/クラスをいくつか定義したモジュールがあるとします(「a」をそのようなエンティティにします)。
module1:
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
同様の質問が過去(2日前、d'uh)に尋ねられ、いくつかの解決策が提案されましたが、これらが私の要件に実際に合うとは思いません。ここに私の特定のコンテキストがあります:
MySQLデータベースサーバーに接続し、データをGUIで表示/変更するPythonプログラムを作成しようとしています。わかりやすくするために、補助/ユーティリティのMySQL関連関数の束を別のファイルで定義しました。ただし、これらの変数にはすべて、最初にユーティリティモジュール内で定義した共通の変数があり、これはMySQLdbモジュールのカーソルオブジェクトです。カーソルオブジェクト(dbサーバーとの通信に使用される)はメインモジュールで定義する必要があることを後で理解しました。これにより、メインモジュールとそれにインポートされるすべてのオブジェクトがそのオブジェクトにアクセスできるようになります。
最終結果は次のようになります:
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 *
そして、ユーティリティ関数のいずれかを呼び出そうとすると、前述の「グローバル名が定義されていません」エラーがトリガーされます。
特に、次のようなユーティリティファイルに「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 *
しかし、それは循環インポートまたはそのようなものであり、最終的にはクラッシュします。だから私の質問は:
メインモジュールで定義された「cur」オブジェクトを、インポートされた補助関数から見えるようにするにはどうすればよいですか。
解決策が他の場所に投稿されている場合は、お時間をいただきありがとうございます。自分で答えを見つけることができず、本にこれ以上のトリックはありません。
db
(そしてcur
、あなたが主張する場合)の両方がその別のモジュールへprogram
とutilities_module
から、それをインポートします。そうすれば、循環依存関係(プログラムがインポートするモジュールからプログラムをインポートすること)とそれに伴う混乱が発生しなくなります。
fetch_all
2つのリストを繰り返し処理する代わりに、ロックステップで2つのカーソルを繰り返し処理することができます)または、データベースを使用して、競合なしに2つの異なるスレッド/グリーンレット/コールバックチェーン/何でも持つことができます)。