开发者

Using a module variable within a class instance

I have a class which is instantiated many times. It re开发者_开发知识库quires 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)


Works for me

>>> class MyClass( object ):
...     def aFunc( self ):
...         print( some_global )
... 
>>> some_global= 3
>>> x= MyClass()
>>> x.aFunc()
3

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:

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')

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 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:

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)) 

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:

def my_func(self):
    print('the_parameter == ' + str(self.__class__.the_parameter)) 


Put global the_parameter in the function to fix the issue.


If you don't declare var as global and don't initialize it, accessing value of non-defined variable is error

so

global the_parameter = config.getint(...)

is the answer

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜