开发者

Python nested objects unable to retrieve value in function

开发者 https://www.devze.com 2023-03-28 19:49 出处:网络
I am trying to build a tree structure that represents a parsed configuration file (the configuration file has a hierarchical structure to it).I represented this as:

I am trying to build a tree structure that represents a parsed configuration file (the configuration file has a hierarchical structure to it). I represented this as:

class configContainer():

    treeDict = {}
    instances = {}

class configObject():

    def __init__(self, name, configLine, parent):
        self.name = name                # Assign to the line number to make unique
        self.parent = parent            
        self.children = []
        self.configLine = configLine    # Actual line of the configuration
        configContainer.instances[name] = self

The configContainer contains a set of objects. configContainer.instances uses a key of "line#" to map to the object. treeDict does a similar mapping, but with a different key (I create treeDict after the entire container is created).

I then t开发者_JAVA技巧ry to reference two objects inside two different configContainers. This works fine from __main__. But when I pass the two configContainers to a function, instances always returns objects from configContainer2

if __name__ == "__main__":


    f1 = open('rfile', 'r')
    configFile1 = f1.read()
    f1.close()

    configTree1 = parseConfig(configFile1)
    configTree1.treeDict = createTreeDict(configTree1)
    zObject1 = configTree1.instances["line10"]


    f2 = open('sfile', 'r')
    configFile2 = f2.read()
    f2.close()

    configTree2 = parseConfig(configFile2)
    configTree2.treeDict = createTreeDict(configTree2)
    zObject2 = configTree2.instances["line10"]

    print "\n\nFrom __main__"
    print "###########################"
    print configTree1
    print configTree2
    print zObject1
    print zObject2


    compareConfigurations(configTree1, configTree2)


def compareConfigurations(tmpTree1, tmpTree2):

    print "\n\nFrom compareConfigurations"
    print "###########################"
    print tmpTree1
    print tmpTree2
    zObject1 = tmpTree1.instances["line10"]
    zObject2 = tmpTree2.instances["line10"]
    print zObject1
    print zObject2

Result is:

### From __main__

<__main__.configContainer instance at 0xb77a34ec>

<__main__.configContainer instance at 0xb740a68c>

<__main__.configObject instance at 0xb740e3ac>

<__main__.configObject instance at 0xb7414bcc>


### From compareConfigurations

<__main__.configContainer instance at 0xb77a34ec>

<__main__.configContainer instance at 0xb740a68c>

<__main__.configObject instance at 0xb7414bcc>

<__main__.configObject instance at 0xb7414bcc>

I can't figure out why I am always getting back the 0xb7414bcc object from inside compareConfigurations?


configContainer.instances is a class attribute, so if you modify it for any instance of a class it will change for all instances of that class. With your current code any time you create a new configObject with the same name it will overwrite the entry in configContainer.instances for that name. You should either make instances an instance attribute of configContainer or make sure your configObjects have different names.

class configContainer():
    def __init__(self):
        self.instances = {}
...

Here is a quick example of what is happening:

>>> cc1 = configContainer()
>>> cc2 = configContainer()
>>> cc1.instances["line10"] = "foo"
>>> configContainer.instances
{'line10': 'foo'}
>>> cc2.instances["line10"] = "bar"
>>> configContainer.instances
{'line10': 'bar'}
>>> cc1.instances
{'line10': 'bar'}


You are aware that configContainer.instances doesn’t access a instance variable, right?

if you want to refer to the wrapping class, you will have to do something like this:

class configContainer(object):
    treeDict = {}
    instances = {}

    def configObject(self, name, configLine, parent):
        return _configObject(self, name, configLine, parent)

    class _configObject(object):
        def __init__(self, container, name, configLine, parent):
            self.name = name                # Assign to the line number to make unique
            self.parent = parent            
            self.children = []
            self.configLine = configLine    # Actual line of the configuration
            container.instances[name] = self


Something either in parseConfig or createTreeDict is corrupting your instances dictionary.

Notice that in main you get both zObject1 and zObject2 from configTree1:

zObject1 = configTree1.instances["line10"]
#...
zObject2 = configTree1.instances["line10"]
#
print zObject1
print zObject2

Which you said produces:

<__main__.configObject instance at 0xb740e3ac>

<__main__.configObject instance at 0xb7414bcc>

If you posted the source to parseConfig and createTreeDict we could get to the root of it.

0

精彩评论

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

关注公众号