Добавление экземпляров объекта в список работает только с длительной копией, как я могу это изменить?

У меня есть класс pymzml.run.Reader из пакета pymzml. Это объект генератора, при циклическом прохождении он выдает экземпляры класса Spectrum (также из пакета pymzml). Я сравниваю разные случаи друг с другом. Поскольку pymzml.run.Reader является объектом-генератором, после их циклического перемещения они больше не могут быть использованы, поэтому я сохраню их в списке для сравнения в дальнейшем.

Однако, когда я сохраняю их в списке, а затем перебираю список, печатая идентификаторы спектров, он показывает, что он сохраняет только последний спектр. Чтобы уточнить:

import pymzml

def test(msrun):
    for spectrum in msrun:
        print spectrum['id']            
        spectrumList.append(spectrum)
    print '-'*20
    for i in spectrumList:
        print i['id']

msrun = pymzml.run.Reader(r'JG_Ti02-C1-1_C2-01A_file1.aligned.mzML')

дает:

1
2
3
4
5
--------------------
5
5 
5 
5
5

В pymzml есть функция deRef(), которая делает глубокую копию спектра, поэтому следующее работает правильно:

import pymzml

def test(msrun):
    for spectrum in msrun: 
        print spectrum['id']
        spectrumList.append(spectrum.deRef())

msrun = pymzml.run.Reader(r'JG_Ti02-C1-1_C2-01A_file1.aligned.mzML') 

Однако создание глубоких копий является основным узким местом, которое я пытаюсь устранить из своего приложения. Как я могу добавить экземпляры спектра в список, чтобы не только последний спектр добавлялся несколько раз?

1 ответ

Решение

Это не может быть просто сохранение последнего спектра - вы делаете все правильно, чтобы сохранить каждый объект в списке.

Проблема в том, что вы получаете один и тот же объект снова и снова.

печать id(spectrum) в цикле, чтобы получить его адрес памяти, покажет, что это один объект, повторенный с его id и другие атрибуты изменены.

Хотя вам не обязательно copy.deepcopy()Вам нужно сделать копию. Пытаться copy.copy()и посмотрите на источник Spectrum.decRef() чтобы увидеть, как это делает его копирование.

Скорее всего, вам нужно decRef() каждый, чтобы сделать их независимыми - иначе, почему класс предоставил бы специальный метод?

Другие вопросы по тегам