我的程序的高级图片
- 目的:解析一个XML文件并将文本保存到类似的python对象中
- 问题:每次我创建一个新的 python 对象并将其附加到列表时,它似乎没有创建一个新对象,而是附加了对先前对象的引用。
我的预期结构的总结:
每个包含连接列表的应用程序列表
app1:
connection1
connection2
app2:
connection3
connection4
connection5
这就是它应该做什么的总结...所以这是我的主要功能:
def main(self):
root = get_xml_root()
root.get_applications()
for application in root.applications:
application.get_connections() ## this is where the memory goes bad!!!
for connection in application.connections:
connection.do_something()
我怎么知道内存有问题:
- 当我更改属于特定应用程序的一个连接列表中的一件事时,另一个应用程序中的连接也会更改。
- 我打印出连接的内存位置,发现有重复的引用(参见内存打印)
内存打印输出
- 当我打印出应用程序位置时,我得到了以下信息(它不是很漂亮,但你可以看到至少地址是不同的):
generator_libraries.data_extraction.extraction.Application_XML instance at 0x15a07e8 - memory location = 22677480 generator_libraries.data_extraction.extraction.Application_XML instance at 0x15a0758 - memory location = 22677336 generator_libraries.data_extraction.extraction.Application_XML instance at 0x15a0830 - memory location = 22677552 generator_libraries.data_extraction.extraction.Application_XML instance at 0x15a0878 - memory location = 22677624 generator_libraries.data_extraction.extraction.Application_XML instance at 0x15a08c0 - memory location = 22677696 generator_libraries.data_extraction.extraction.Application_XML instance at 0x15a0908 - memory location = 22677768 generator_libraries.data_extraction.extraction.Application_XML instance at 0x15a0950 - memory location = 22677840 generator_libraries.data_extraction.extraction.Application_XML instance at 0x15a0998 - memory location = 22677912 generator_libraries.data_extraction.extraction.Application_XML instance at 0x15a09e0 - memory location = 22677984 generator_libraries.data_extraction.extraction.Application_XML instance at 0x15a0a28 - memory location = 22678056
当我打印出 3 个不同应用程序的连接位置时,我得到以下信息(您可以看到地址之间的重复):
- app1::
- 内存位置= 22721168
- 内存位置 = 22721240
- 内存位置= 22721024
- 内存位置= 22721600
内存位置 = 22721672
应用2:
- 内存位置 = 22721240
- 内存位置= 22721672
- 内存位置= 22721600
- 内存位置= 22721168
- 内存位置= 22722104
- 内存位置 = 22722176
内存分析的结论 似乎每次我创建一个新的连接对象并将其附加到我的“连接”列表时,它不是创建一个新对象,而是从我以前的对象中获取内存引用。
问题函数代码的更详细 View
class Application_XML(XML_Element_Class):
name = None
connections=copy.deepcopy([])
xml_element=None
def get_connections(self):
xml_connections = self.get_xml_children()
for xml_connection in xml_connections:
connection = None ## reset the connection variable
connection = Connection_XML(xml_connection)
connection.unique_ID = connection_count
self.connections.append(copy.deepcopy(connection))
del connection ## reset where its pointing to
connection_count+=1
self.log_debugging_info_on_connection_memory() ### this is where I look at memory locations
一个做同样事情的类......但有效
class Root_XML(XML_Element_Class):
applications = copy.deepcopy([])
def get_applications(self):
xml_applications = self.get_xml_children()
for xml_application in xml_applications:
self.applications.append(Application_XML(xml_application))
self.log_application_memory_information()
如果有任何帮助,这里是连接类:
class Connection_XML(XML_Element_Class):
### members
name = None
type = None
ID = None
max_size = None
queue_size = None
direction = None
def do_something(self):
pass
最后的话
我已经尝试了书中几乎所有的技巧,包括创建对象的替代方法、创建对象后销毁它们……但仍然无济于事。我觉得答案背后可能有一个基本的 python 内存概念......但是在我所有的在线搜索之后,没有任何东西可以揭示答案。
拜托,如果你能提供帮助那就太棒了!!!谢谢:)
最佳答案
我认为问题与您正在查看的部分没有任何关系,而是与 Connection_XML
类有关:
class Connection_XML(XML_Element_Class):
### members
name = None
type = None
ID = None
max_size = None
queue_size = None
direction = None
def do_something(self):
pass
所有这些成员都是类属性。每个 Connection_XML
实例共享一个 name
,一个 type
等。因此,即使您的实例都是唯一的对象,改变一个改变所有这些。
您需要实例属性——每个实例的单独名称
等。您这样做的方法是动态创建属性,通常是在 __init__
方法中:
class Connection_XML(XML_Element_Class):
def __init__(self):
self.name = None
self.type = None
self.ID = None
self.max_size = None
self.queue_size = None
self.direction = None
def do_something(self):
pass
如果没有真正的 SSCCE,很难确定这是您的问题.在这个玩具示例中,所有属性的值都是 None
,它是不可变的,因此不会真正导致此类问题。但是,如果其中之一是列表或具有自己属性的对象,它就会。
关于python如何在不重复的情况下将新对象保存到列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18392928/