我正在尝试构建一个表示已解析配置文件的树结构(配置文件具有层次结构)。我把它表示为:
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
configContainer
包含一组对象。 configContainer.instances
使用“line#”键映射到对象。 treeDict
执行类似的映射,但使用不同的键(在创建整个容器后创建treeDict
)。
然后我尝试在两个不同的configContainers
中引用两个对象。这可以从__main__
开始正常工作。但是当我将两个configContainers
传递给一个函数时,实例总是从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
结果是:
### 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>
我无法弄清楚为什么我总是从compareConfigurations
内部取回0xb7414bcc对象?
答案 0 :(得分:4)
configContainer.instances
是一个类属性,因此如果您为类的任何实例修改它,它将针对该类的所有实例进行更改。使用当前代码,只要您创建具有相同名称的新configObject
,它就会覆盖configContainer.instances
中该条目的条目。您应该instances
configContainer
的实例属性,或者确保configObjects
具有不同的名称。
class configContainer():
def __init__(self):
self.instances = {}
...
以下是正在发生的事情的一个简单示例:
>>> cc1 = configContainer()
>>> cc2 = configContainer()
>>> cc1.instances["line10"] = "foo"
>>> configContainer.instances
{'line10': 'foo'}
>>> cc2.instances["line10"] = "bar"
>>> configContainer.instances
{'line10': 'bar'}
>>> cc1.instances
{'line10': 'bar'}
答案 1 :(得分:2)
您知道configContainer.instances
无法访问实例变量,对吗?
如果你想引用包装类,你必须做这样的事情:
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
答案 2 :(得分:1)
parseConfig
或createTreeDict
中的某些内容正在破坏您的instances
词典。
请注意,在主要内容中,您从zObject1
获得 <{strong> zObject2
和configTree1
:
zObject1 = configTree1.instances["line10"]
#...
zObject2 = configTree1.instances["line10"]
#
print zObject1
print zObject2
你说的是:
<__main__.configObject instance at 0xb740e3ac>
<__main__.configObject instance at 0xb7414bcc>
如果您将来源发布到parseConfig
和createTreeDict
,我们可以找到它的根源。