我已经跑入了一个在Python脚本中导入模块的墙壁。我会尽我所能来描述错误,为什么我会遇到它,以及为什么我要搭配这种特殊的方法来解决我的问题(我将在第二秒中描述):Python - 导入模块中全局变量的可见性
让我们假设我有一个模块其中我定义一些效用函数/类,其是指在向其中该辅助模块将被导入的命名空间中定义的实体(让“一”是这样的实体):
模块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
过去Similar questions have been asked(前两天,德呃)和几个解决方案已经提出,但是我真的不认为这些符合我的要求。 这里是我的特定上下文:
我试图做一个Python程序连接到MySQL数据库服务器,并显示/修改数据与GUI。为了清晰起见,我在一个单独的文件中定义了一大堆辅助/实用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 *
然后,只要我尝试调用任何实用程序功能,就会触发a前面提到的“全球名称未定义”错误。
一个特别的建议是有一个 “从程序导入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”对象,在主模块中定义,可见的导入到它的辅助功能?
感谢您的时间和我最深的歉意,如果解决方案已发布到别处。我自己找不到答案,我的书里没有更多的技巧。
根据您的更新:您可能不希望单个共享游标。一个共享的_connection_,是的,但是游标很便宜,并且通常有很多理由让多个游标同时存在(例如,所以你可以以锁步方式遍历其中的两个,而不必'fetch_all'并遍历两个列表,或者只是让你有两个不同的线程/ greenlets/callback-chains /不管使用数据库而没有冲突)。 – abarnert 2013-04-11 22:57:47
无论如何,无论你想分享什么,我想这里的答案是将'db'(和'cur',如果你坚持的话)放入一个单独的模块中,'program'和'utilities_module'将它们从中导入。这样你就不会得到循环依赖(从程序导入的模块导入程序)以及随之而来的混乱。 – abarnert 2013-04-11 22:58:50