【发布时间】:2013-08-23 00:37:59
【问题描述】:
我的程序的高级图片
- 目的:解析 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 实例位于 0x15a07e8 - 内存位置 = 22677480 generator_libraries.data_extraction.extraction.Application_XML 实例位于 0x15a0758 - 内存位置 = 22677336 generator_libraries.data_extraction.extraction.Application_XML 实例位于 0x15a0830 - 内存位置 = 22677552 generator_libraries.data_extraction.extraction.Application_XML 实例位于 0x15a0878 - 内存位置 = 22677624 generator_libraries.data_extraction.extraction.Application_XML 实例位于 0x15a08c0 - 内存位置 = 22677696 generator_libraries.data_extraction.extraction.Application_XML 实例位于 0x15a0908 - 内存位置 = 22677768 generator_libraries.data_extraction.extraction.Application_XML 实例位于 0x15a0950 - 内存位置 = 22677840 generator_libraries.data_extraction.extraction.Application_XML 实例位于 0x15a0998 - 内存位置 = 22677912 generator_libraries.data_extraction.extraction.Application_XML 实例位于 0x15a09e0 - 内存位置 = 22677984 generator_libraries.data_extraction.extraction.Application_XML 实例位于 0x15a0a28 - 内存位置 = 22678056
-
当我打印出 3 个不同应用程序的连接位置时,我得到以下信息(您可以看到地址之间的重复):
- app1::
- 内存位置 = 22721168
- 内存位置 = 22721240
- 内存位置 = 22721024
- 内存位置 = 22721600
内存位置 = 22721672
app2:
- 内存位置 = 22721240
- 内存位置 = 22721672
- 内存位置 = 22721600
- 内存位置 = 22721168
- 内存位置 = 22722104
- 内存位置 = 22722176
记忆分析的结论 似乎每次我创建一个新的连接对象并将其附加到我的“连接”列表时,它都不会创建一个新对象,而是从我以前的对象中获取内存引用。
问题函数代码的更详细视图
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内存概念......但是在我网上搜索之后,没有任何答案。
拜托,如果你能帮忙,那就太棒了!!!谢谢:)
【问题讨论】:
-
等等,你从一月份开始有 Python 问题。我很惊讶你 8 个月没有被这个咬伤。
-
Bug:与其他语言不同,在类范围内分配给变量不会声明实例字段;它设置了一个类属性。如果需要实例属性,请在
__init__方法中设置self.attribute_name = whatever_value。 -
如果您发布一个 SSCCE 来运行并演示我们可以为您解决的问题,而不仅仅是发布代码片段和描述,这将非常有帮助。
-
除了关于类和实例变量的 cmets,
connections=copy.deepcopy([])是多余的。使用connections=[](或更可能是self.connections=[])创建了一个新列表,您不需要复制它。
标签: python arrays memory-management pass-by-reference class-instance-variables