在类实例中使用模块变量
我有一个被实例化多次的类。它需要配置文件中的某个参数。我想到在模块级别读取一次配置文件,以便每个实例都可以引用加载的参数。
我在收到消息时可能遗漏了一些内容:UnboundLocalError: 赋值前引用的局部变量“the_parameter”
以下是代码的概要:
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)
I have a class which is instantiated many times. It requires a certain parameter from a configuration file. I thought of reading the config file once in the module level so that each instance can refer to the loaded parameter.
I'm probably missing something as I'm receiving:UnboundLocalError: local variable 'the_parameter' referenced before assignment
Here's the outline of the code:
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
对我有用
发布的代码可能删除了太多细节以显示真正的错误。
Works for me
The code that's posted has probably had too many details removed to show the real error.
不要尝试在类中使用全局变量,这在某种程度上违背了类的目的。如果你的类需要一个配置对象,你可以通过依赖注入传递它,即显式地将它作为参数传递给你的类:
顺便说一句,如果你真的只需要单个参数,你当然可以传递参数而不是整个配置对象。如果将来可能需要其他参数,传递配置对象将是更好的选择。
Don't try to use global variables in your classes, this is somewhat against the purpose of classes. If your class requires a config object, you could pass it via dependency injection, i.e. explicitely pass it as an argument to your class:
Btw if you really only need the single parameter, you can of course pass the parameter instead of the whole config object. If you might need other parameters in the future, passing the config object would be the better choice.
S.Lott 是对的:OP 的代码有效。
它可以与类定义之前或之后定义的 the_parameter 一起使用,这并不重要。
发生的情况是,当函数 my_func 作为实例之一的方法被调用时,会在 my_func 的环境中搜索对象 the_parameter > 的代码块,也就是说:先在函数的本地作用域内,然后在函数外,直到全局命名空间(=模块级别),因为”在代码块中使用名称时,它是使用最近的封闭解决的范围。” (ref)
所以没有需要找到一个不存在的问题的解决方案。
。
然而,在我看来,这段代码可以改进,因为它本身就意味着必须在全局级别绑定的所有对象中找到 the_parameter ,并且这些对象可能非常多。
在函数代码中定义
global the_parameter
缩短了研究过程:执行将直接在全局级别搜索对象,而无需探索函数的名称空间。但无论如何,在这两种情况下,这是一个糟糕的过程,与类的目的相反,正如jena所强调的那样:实例必须是一个自给自足的对象,具有提供所有内容的字段。其功能所必需的。
。
jena 的解决方案还不是最好的,因为它意味着每次创建实例时都必须将 the_parameter 作为参数传递。
如果 the_parameter 旨在对 MyClass 的所有实例始终通用,则代码应使其成为与 MyClass 的所有实例更严格关联的对象强>。
所以在我看来,下面的代码更方便:
这样做,the_parameter的搜索将通过探索类的名称空间来完成,而不是在广阔的全局名称空间中。
。
更新
好吧,我意识到要找到 MyClass.the_parameter ,执行必须首先在全局命名空间中搜索对象 MyClass ,这消除了我假装的东西。
为了避免在全局命名空间中搜索,必须像这样调用实例的 _class_ 属性:
S.Lott is right: the OP's code works.
It works either with the_parameter defined before the class's definition or after, it doesn't matter.
What happens is that when the function my_func is called as a method of one of the instances, the object the_parameter is searched in the environment of the my_func's code block, that is to say: first in the local scope of the function, then outside the function, until the global namespace (= module level), because "When a name is used in a code block, it is resolved using the nearest enclosing scope." (ref)
So there's no need to find a solution to a problem that doesn't exist.
.
However, this code can be improved IMO, because, as it is, it implies that the_parameter must be found among all the objects binded at the global level, and these objects are possibly very numerous.
Defining
global the_parameter
inside the function's code shortens the process of research: the execution will go directly at the global level to search the object, without exploring the function's namespace.But anyway, in these two cases, it is a poor process, contrary to the the purpose of classses, as underlined by jena : an instance must be a self-sufficient object having fields that provide all that is necessary to its functionning.
.
The solution of jena isn't the best yet, because it implies that the_parameter must be passed as argument each time an instance will be created.
If the_parameter is intended to be invariably common to all the instances of MyClass, the code should make it a more strictly associated object to all the instances of MyClass.
So it seems to me that the following code is the more convenient:
Doing so, the search of the_parameter will be done by exploring the namespace of the class, not in the vast global namespace.
.
Update
Well, I realize that to find MyClass.the_parameter , the execution must first search the object MyClass in the global namespace, and that anihilates what I pretended.
To avoid the search in the global namespace, the call to the _class_ attribute of the instance must be done like that:
如果您没有将 var 声明为全局变量并且没有初始化它,则访问未定义变量的值是错误的,
所以
答案也是如此
If you don't declare var as global and don't initialize it, accessing value of non-defined variable is error
so
is the answer
将
global the_parameter
放入函数中以解决问题。Put
global the_parameter
in the function to fix the issue.