如何复制对象而不引用它?

2024-05-29 11:53:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我不确定我的标题是否与我所寻找的相符,但我认为引用是问题所在。在

我有一个Reader对象,可以通过它循环:

msrun = pymzml.run.Reader(mzmlFile)
for feature in msrun:
    print feature['id']

通过这段代码,我得到了msrun中所有特性的id,从1开始。但是,我需要先遍历代码,然后获取所有我想要的键并将它们放入一个列表中,如下所示:

^{pr2}$

但是,如果我运行以下代码:

msrun = pymzml.run.Reader(mzmlFile)
specKeys, precursKeys = getKeys(msrun, ['title','name'])
for feature in msrun:
    print feature['id']

它从getKeys()中没有循环的id开始(从11开始,而不是从1开始)。所以我想pymzml.run.Reader()的工作方式类似于生成器对象。所以我试着复制这个物体。首先我试过了

copyMsrun = msrun
specKeys, precursKeys = getKeys(copyMsrun, ['title','name'])

但如果我理解正确的话,这也会产生同样的问题,因为做copyMsrun=msrun会让它们指向同一个东西。在

然后我试过了

import copy
copyMsrun = copy.copy(msrun)

但我还是有同样的问题。我用过复制。复制而不是复制.deepcopy因为我不认为Reader对象包含其他对象,当我尝试deepcopy时

TypeError: object.__new__(generator) is not safe, use generator.__new__().

那么如何复制一个对象,这样循环通过一个对象不会影响另一个对象?我应该这么做吗

msrun = pymzml.run.Reader(mzmlFile)
copyMsrun = pymzml.run.Reader(mzmlFile)

是吗?在


编辑: 对于艾德玉的评论,我也试过了,但当我这么做的时候

spectrumList = []
for spectrum in msrun:
    print spectrum['id']
    spectrumList.append(spectrum)

for spectrum in spectrumList:
    print spectrum['id']

第一次打印的结果是1-10,但第二次打印的结果是10乘以10


Tags: 对象run代码inidforfeaturereader
3条回答

试试itertools.tee,这给了你独立的迭代器。如果这不起作用,您可能就有麻烦了,因为生成器生成的对象依赖于某种外部状态,(id=number of objects degreated to such?),在这种情况下没有办法自动提供帮助。deepcopy是您的最佳选择,但是如果这不起作用,您就必须编写自己的类来捕获spectrum对象的所有信息。在

spectrumList = []
for spectrum in msrun:
    spectrumList.append(MySpectrum(spectrum))

或者更短的变种

^{pr2}$

你需要的是

class MySpectrum:
    def __init__(self, spectrum):
        self.id = spectrum.id
        ...

从pymzML的出版和文献来看,很明显这种“病理学设计”是有目的的。初始化数千个频谱对象将产生巨大的计算开销、内存和cpu周期,而这些都是根本不需要的。通常,解析大量的mzML自然需要边解析边分析的方法,而不是收集以后需要分析的所有内容。在

尽管如此,pymzML仍然提供了“深度复制”频谱的功能,只需调用光谱.deRef(). 使用此函数的优点是,在复制之前,所有不必要的数据都将被剥离,从而提供更小的对象。pymzML deRef

  run = pymzml.run.Reader(file_to_read, MS1_Precision = 5e-6, MSn_Precision = 20e-6)
  for spec in run:
   tmp = spec.deRef()

希望有帮助。在

看起来你在处理一个病态设计的类。您使用的库中有一些严重的缺陷,尤其是迭代器反复生成相同对象的部分。在

您可能需要复制迭代器的输出,如下所示:

objs = [copy.deepcopy(obj) for obj in pymzml.run.Reader(mzmlFile)]

for obj in objs:
    # do something
for obj in objs:
    # do something

如果这不起作用,你需要找到谁写的图书馆和没收他们的电脑。在

相关问题 更多 >

    热门问题