python如何在不重复的情况下将新对象保存到列表中

标签 python arrays memory-management pass-by-reference class-instance-variables

我的程序的高级图片

  • 目的:解析一个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/

相关文章:

python - 两个日期之间的差异(日期时间)

python - 是否有用于 Python 的 GPS 库?

python numpy : loading files to list, 并转换为数组,但错误 "array is too big."

c++ - 为什么编译器推迟 std::list 释放?

iOS开发: How am I mismanaging memory in this code?

linux - 将 ELF 共享库和自定义 binfmt 可执行文件加载到同一 Linux 地址空间

python - 无法将 'list' 对象隐式转换为 str python

python - 从标签列表中快速获取项目 x (在数据中)的标签的方法

c++ - 将数组导出到txt文件

java - 在 Java 中将 JSON 数组解析为字符串输出(Echo Nest)