我在 Python 脚本中导入模块时遇到了一些麻烦。我会尽力描述错误,为什么会遇到它,以及为什么我要使用这种特殊的方法来解决我的问题(我将在稍后描述):
假设我有一个模块,我在其中定义了一些实用程序函数/类,它们引用了将要导入此辅助模块的命名空间中定义的实体(让“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
Similar questions have been asked在过去(两天前,d'uh)并提出了几种解决方案,但我并不认为这些符合我的要求。 这是我的特定背景:
我正在尝试制作一个 Python 程序,它连接到 MySQL 数据库服务器并使用 GUI 显示/修改数据。为了简洁起见,我在一个单独的文件中定义了一堆与 MySQL 相关的辅助/实用程序函数。但是它们都有一个公共(public)变量,我最初在实用程序模块中定义了 inside,它是 MySQLdb 模块中的 cursor 对象。 后来我意识到 cursor 对象(用于与 db 服务器通信)应该在主模块中定义,这样主模块和导入到其中的任何东西都可以访问该对象。
最终结果会是这样的:
utilities_module.py:
def utility_1(args):
code which references a variable named "cur"
def utility_n(args):
etcetera
还有我的主模块:
程序.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
程序.py:
import Tkinter, MySQLdb
db=MySQLdb.connect(#blahblah) ; cur=db.cursor() #cur is defined!
from utilities_module 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 - 导入模块中全局变量的可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15959534/
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我正在编写一个方法,它将在一个类中定义一个实例方法;类似于attr_accessor:classFoocustom_method(:foo)end我通过将custom_method函数添加到Module模块并使用define_method定义方法来实现它,效果很好。但我无法弄清楚如何考虑类(class)的可见性属性。例如,在下面的类中classFoocustom_method(:foo)privatecustom_method(:bar)end第一个生成的方法(foo)必须是公共(public)的,第二个(bar)必须是私有(private)的。我怎么做?或者,如何找到调用我的cust
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c