【问题标题】:Save class upon deletion, load class upon instantiation: loaded class does not contain previously created attributes删除时保存类,实例化时加载类:加载的类不包含先前创建的属性
【发布时间】:2022-01-12 00:00:37
【问题描述】:

我有一个 python 类,表示来自特定主题的分组 Dicom 系列,在模块 dicom_parser.py 中定义。实例化时,该类调用通过 UID 读取和排序 Dicom 的方法。

import os
import pydicom as pdi

class DicomSeries():
    def __init__(self):
        self._dcm_unsort_headers = self._dicom_parse("/home/hamilton/dicoms/XYZ_fmri_2011")
        self.dcm_grouped = self._dicom_sort(self._dcm_unsort_headers)
        delattr(self, "_dcm_unsort_headers")

    @staticmethod
    def _dicom_parse(dcm_dir):
        # Find and parse all, return unsorted list
        return dcm_headers

    @staticmethod
    def _dicom_sort(dcm_headers):
        # Sort list of dcm_headers by UID
        return dcm_grouped

dicom_parser.py 是从 main.py 脚本导入和调用的。

我编写了一个保存和加载方法,取自 bivouac0 在this post 上的回答。通过weakref.finalize 调用save(),而在调用__init__() 时如果保存的文件存在则调用load()

import os
import pickle
from weakref import finalize

class DicomSeries():
    def __init__(self, filename = 'XYZ_dcms.pkl.gz'):
        if os.path.exists(filename) is True
            self = self.load()
        else:
            # Load and sort
        self._finalizer = finalize(self, self.save, filename = self.filename)
    def save(self, filename = None):
        if filename is None:
            filename = self.filename
        with gzip.open(filename, 'wb') as f:
            pickle.dump(self, f, protocol=pickle.HIGHEST_PROTOCOL)
    def load(self, filename = None):
        if filename is None:
            filename = self.filename
        with gzip.open(filename, 'rb') as f:
            old = pickle.load(f)
        return old

类在删除或脚本退出时保存成功;但是,如果在新的脚本调用中再次实例化该对象,则加载的对象将失去在前一个实例中声明的所有属性(例如,sub.dcm_grouped 未定义)。

我该如何解决这个问题并实现以下行为:

  1. 在对象删除或脚本退出(即 gc)时保存实例
  2. 如果存在filename,则在对象实例化时加载实例。

【问题讨论】:

  • 是 dcm_grouped 还是 grouped_dcm?
  • 在方法中分配给self 在该方法之外绝对没有效果。如果要在__init__() 中进行加载,则必须将加载对象中的所有属性复制到现有的self 对象中。
  • 应该是 dcm_grouped。编辑修复。

标签: python class pickle


【解决方案1】:

为了在每次实例化时取消保存的类,我需要修改__init__,将self = self.load() 替换为self.__dict__ = self.load().__dict__

class DicomSeries():
    def __init__(self, filename = 'XYZ_dcms.pkl.gz'):
        if os.path.exists(filename) is True
            self = self.load()

class DicomSeries():
    def __init__(self, filename = 'XYZ_dcms.pkl.gz'):
        if os.path.exists(filename) is True
            self.__dict__ = self.load().__dict__

这实现了所需的行为,即:在重新实例化时重新加载保存的腌制类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多