繁体   English   中英

在 class 实例中使用模块变量

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM