[英]Using a module variable within a class instance
我有一个多次实例化的 class。 它需要配置文件中的某个参数。 我想在模块级别读取一次配置文件,以便每个实例都可以引用加载的参数。
我可能在收到以下信息时遗漏了一些东西:
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)
为我工作
>>> class MyClass( object ):
... def aFunc( self ):
... print( some_global )
...
>>> some_global= 3
>>> x= MyClass()
>>> x.aFunc()
3
发布的代码可能删除了太多细节以显示真正的错误。
不要试图在你的类中使用全局变量,这有点违背类的目的。 如果您的 class 需要配置 object,您可以通过依赖注入传递它,即将它作为参数显式传递给您的 class:
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')
顺便说一句,如果你真的只需要单个参数,你当然可以传递参数而不是整个配置 object。 如果您将来可能需要其他参数,传递配置 object 将是更好的选择。
将global the_parameter
放入 function 以解决此问题。
S.Lott 是对的:OP 的代码有效。
它可以与在类定义之前或之后定义的the_parameter一起使用,没关系。
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在 function 之外,直到全局命名空间(= 模块级别),因为“当在代码块中使用名称时,它使用最近的封闭 scope 解析。” (参考)
因此,没有必要为不存在的问题找到解决方案。
.
但是,IMO 可以改进此代码,因为它实际上意味着必须在全局级别绑定的所有对象中找到the_parameter ,并且这些对象可能非常多。
在函数代码中定义global the_parameter
缩短了研究过程:执行将 go 直接在全局级别搜索 object,而无需探索函数的命名空间。
但无论如何,在这两种情况下,这是一个糟糕的过程,与类的目的相反,正如 jena 强调的那样:一个实例必须是一个自给自足的object具有提供其功能所需的所有字段的字段。
.
jena 的解决方案还不是最好的,因为它意味着每次创建实例时都必须将 the_parameter作为参数传递。
如果_parameter旨在对MyClass的所有实例始终通用,则代码应使其成为与MyClass的所有实例更严格关联的 object。
所以在我看来,下面的代码更方便:
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的搜索将通过探索 class 的命名空间来完成,而不是在广阔的全局命名空间中。
.
好吧,我意识到要找到MyClass.the_parameter ,执行必须首先在全局命名空间中搜索 object MyClass ,这会破坏我的假装。
为避免在全局命名空间中搜索,对实例的_class _属性的调用必须按如下方式进行:
def my_func(self):
print('the_parameter == ' + str(self.__class__.the_parameter))
如果您不将 var 声明为全局并且不对其进行初始化,则访问未定义变量的值是错误的
所以
global the_parameter = config.getint(...)
是答案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.