Укроп Python: KeyError: 'ClassType'

Я пытаюсь засолить класс. Pickle завершается с ошибкой атрибута, поскольку конструктор класса отсутствует во время загрузки. Я понял, что модуль dill является расширением модуля pickle. Тем не менее, я все еще получаю ошибки. А именно:

Traceback (most recent call last):
  File "C:\Users\s4551072\.conda\envs\gpuenv\lib\site-packages\IPython\core\interactiveshell.py", line 3331, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-4-447b415d0f92>", line 1, in <module>
    dill.load(open('hp', 'rb'))
  File "C:\Users\s4551072\.conda\envs\gpuenv\lib\site-packages\dill\_dill.py", line 270, in load
    return Unpickler(file, ignore=ignore, **kwds).load()
  File "C:\Users\s4551072\.conda\envs\gpuenv\lib\site-packages\dill\_dill.py", line 472, in load
    obj = StockUnpickler.load(self)
  File "C:\Users\s4551072\.conda\envs\gpuenv\lib\site-packages\dill\_dill.py", line 577, in _load_type
    return _reverse_typemap[name]
KeyError: 'ClassType'

Что я получаю при загрузке.

При сохранении:

dill.dump(hp, open('hp', 'wb'))

При загрузке (совершенно в другом файле):

dill.load(open('hp', 'rb'))

Где hp является экземпляром следующего класса

import tensorflow as tf
import resources.toolbox as tb

class HParams(tb.HyperParam):
    def __init__(self):
        # =================== Enviroment ========================
        super().__init__()
        self.exp_name = 'trial'  # 'gru_vs_rnn_vs_lstm'
        self.save_path = './tmp/lstm/' + self.exp_name
        self.save_path = os.path.abspath(self.save_path)
        os.makedirs(self.save_path, exist_ok=True)
        self.pkg = tf.__name__
        self.s = tb.get_diag(16, 44)

Я перепробовал всякие уловки, но безрезультатно.

ُEDIT1:

Это основной файл:


import lib
import dill


class HP(lib.HyperParam):
    def __init__(self):
        super().__init__()


if __name__ == '__main__':
    hp = HP()
    dill.dump(hp, open('myfile', 'wb'))

А это lib модуль


import os
import inspect


class HyperParam:
    def __init__(self):
        """
        It is preferable to pass the packages used, so that later this class can be saved and loaded.
        """
        # =================== Enviroment ========================
        self.exp_name = 'default'
        self.root = 'tmp'
        self.pkg = None
        # self.device = config_device(HyperParam, Device.gpu0)
        # ===================== DATA ============================
        self.cal = [False, True][0]
        self.freq_select = None
        self.norm_factor = None
        self.sort_freq = None
        self.dmd = False
        self.seed = 234
        # =================== Model =============================
        self.l1 = 0.0005
        # ===================== Training ========================
        self.split = 0.2
        self.lr = 0.0005
        self.batch_size = 32
        self.epochs = 30
        self.milk = [None]
        self.nsl = [False, True][0]
        self.adv_multiplier = 0.2
        self.adv_step_size = 0.01
        self.adv_grad_norm = 'infinity'

    @staticmethod
    def from_saved(path):
        path = os.path.join(path, f'metadata/HyperParam')
        import pickle
        return pickle.load(open(path, "rb"))()

    def __repr__(self):
        return ''.join(inspect.getsourcelines(self.__class__)[0])

Запустите основной файл, он сохранит и возразит. Теперь в новом файле попробуйте загрузить это:

import dill

a = dill.load(open('myfile', 'rb'))
Traceback (most recent call last):
  File "C:\Users\s4551072\.conda\envs\gpuenv\lib\site-packages\IPython\core\interactiveshell.py", line 3331, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-3-390afbf8b35b>", line 1, in <module>
    a = dill.load(open('./training/myfile', 'rb'))
  File "C:\Users\s4551072\.conda\envs\gpuenv\lib\site-packages\dill\_dill.py", line 270, in load
    return Unpickler(file, ignore=ignore, **kwds).load()
  File "C:\Users\s4551072\.conda\envs\gpuenv\lib\site-packages\dill\_dill.py", line 472, in load
    obj = StockUnpickler.load(self)
  File "C:\Users\s4551072\.conda\envs\gpuenv\lib\site-packages\dill\_dill.py", line 462, in find_class
    return StockUnpickler.find_class(self, module, name)
AttributeError: Can't get attribute 'HP' on <module '__main__'>



person Alex Deft    schedule 26.04.2020    source источник
comment
вы импортируете HParams в файл, который вы делаете dill.load()?   -  person afghanimah    schedule 26.04.2020
comment
@afghanimah Нет. Я понимаю, что если я импортирую его, он все исправит. Но если это так, то pickle так же хорош. Какая польза от dill тогда?   -  person Alex Deft    schedule 26.04.2020
comment
stackoverflow.com/ вопросы/58193119/   -  person afghanimah    schedule 26.04.2020
comment
@afghanimah Я ​​уже прочитал это. Из него я понял, что он расширяет только те типы объектов, которые можно сериализовать, вот и все. Пожалуйста, поправьте меня, если я ошибаюсь.   -  person Alex Deft    schedule 26.04.2020
comment
Это, кажется, мое понимание, а также с первого взгляда   -  person afghanimah    schedule 26.04.2020
comment
@AlexDeft: я dill автор. Трудно сказать, что вы делаете, можете ли вы создать полный минимальный пример, демонстрирующий, как вы создаете свою ошибку? Должен ли я предположить, что hp = HParams()? Какой из dill вариантов сериализации вы пробовали? или диагностические инструменты?   -  person Mike McKerns    schedule 29.04.2020
comment
@MikeMcKerns Привет. Извините, прошло некоторое время, и я пытаюсь сейчас, но мне не удалось воспроизвести ту же ошибку, которую вы просили, однако я получил что-то более знакомое. См. EDIT 1   -  person Alex Deft    schedule 03.05.2020
comment
dill плохо ладит с super. Если я уберу ненужный вызов super, "HP" можно будет сбросить и загрузить. Я пробовал с recurse, установленным на True, а также на False, и оба могут загрузить рассол. Возможно, вы захотите попробовать dill.source.dumpsource.   -  person Mike McKerns    schedule 03.05.2020