我有一个多次实例化的类。它需要配置文件中的某个参数。我想在模块级别读取配置文件一次,这样每个实例都可以引用加载的参数。
我可能在收到的时候遗漏了一些东西:
UnboundLocalError: local variable 'the_parameter' referenced before assignment
以下是代码的大纲:
import ConfigParser
config = ConfigParser.ConfigParser()
config.read('config.cfg')
the_parameter = config.getint('my_section','the_parameter')
class MyClass():
def my_func(self):
print(the_parameter)
答案 0 :(得分:4)
为我工作
>>> class MyClass( object ):
... def aFunc( self ):
... print( some_global )
...
>>> some_global= 3
>>> x= MyClass()
>>> x.aFunc()
3
发布的代码可能删除了太多细节以显示真正的错误。
答案 1 :(得分:3)
不要尝试在类中使用全局变量,这有点违背了类的目的。如果你的类需要一个配置对象,你可以通过依赖注入传递它,即明确地将它作为参数传递给你的类:
config = ConfigParser.ConfigParser()
config.read('config.cfg')
class MyClass(object):
def __init__(self, config):
self._config = config
def my_func(self):
print self._config.getint('my_section', 'the_parameter')
顺便说一句,如果你真的只需要单个参数,你当然可以传递参数而不是整个配置对象。如果您将来可能需要其他参数,那么传递配置对象将是更好的选择。
答案 2 :(得分:1)
将global the_parameter
放入函数中以解决问题。
答案 3 :(得分:1)
S.Lott是对的:OP的代码有效 它适用于在类定义之前或之后定义的 the_parameter ,无关紧要。
当将 my_func 函数作为其中一个实例的方法调用时,会在 my_func的环境中搜索 the_parameter 对象。 的代码块,也就是说:首先在函数的本地范围内,然后在函数外部,直到全局命名空间(=模块级别),因为“当一个名字用于一个代码块,使用最近的封闭范围解析。“(ref)
所以没有必要找到一个不存在的问题的解决方案。
但是,这个代码可以改进IMO,因为它实际上意味着必须在全局级别绑定的所有对象中找到 the_parameter ,并且这些对象可能非常多。
在函数代码中定义global the_parameter
缩短了研究过程:执行将直接在全局级别搜索对象,而不会探索函数的命名空间。
但无论如何,在这两种情况下,这是一个糟糕的过程,与分类的目的相反,如 jena 所强调的:一个实例必须是一个自足的对象,其中包含提供的字段所有这些都是其功能所必需的。
jena 的解决方案还不是最好的,因为它暗示每次创建实例时都必须将 the_parameter 作为参数传递。
如果 the_parameter 对于 MyClass 的所有实例都是通用的,那么代码应该使它成为 MyClass的所有实例的更严格关联的对象强>
所以在我看来,以下代码更方便:
class MyClass(object):
import ConfigParser
config = ConfigParser.ConfigParser()
config.read('config.cfg')
the_parameter = config.getint('my_section','the_parameter')
del ConfigParser,config
def my_func(self):
print('the_parameter == ' + str(MyClass.the_parameter))
这样做, the_parameter 的搜索将通过探索类的名称空间来完成,而不是在庞大的全局名称空间中。
嗯,我意识到要找到 MyClass.the_parameter ,执行必须首先搜索全局命名空间中的对象 MyClass ,并且这会消除我假装的内容。
要避免在全局命名空间中进行搜索,必须按以下方式调用实例的 _ 类 _ 属性:
def my_func(self):
print('the_parameter == ' + str(self.__class__.the_parameter))
答案 4 :(得分:0)
如果您没有将var声明为全局并且不初始化它,则访问未定义变量的值是错误
所以
global the_parameter = config.getint(...)
是答案