Python nested objects unable to retrieve value in function
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.
精彩评论