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

У меня есть класс 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 Ответ

1 голос
/ 29 марта 2012

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

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

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

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

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

...