Загрузка маринованного (укропного) файла, содержащего словарь функций

Это продолжение вопроса, который я ранее задавал: Загрузка функций в файл pickle, который использует оболочку класса, где я хотел выделить словарь функции под оболочками классов, но модуль оболочки класса не смог загрузить.

С тех пор я решил это, используя dill вместо pickle:

func_dict = lowess_record()

wanted = ['func_dict', 'Interp1dPicklable', 'PolyValPicklable', 'dill', '__builtins__', 'wanted']

for name in globals().keys():
    if name not in wanted:
        del globals()[name]

del globals().wanted

with open('./func_dict.p', 'wb') as f:
    dill.dump(globals(), f)

Я удалил некоторые ненужные переменные (участвующие в создании func_dict из данных) из globals(), они не были нужны, так как я хотел работать только с func_dict.

Теперь, когда я загружаю маринованный файл, используя:

func_dict_loaded = dill.load(open("./func_dict.p", "rb"))

Я получил:

<In> func_dict_loaded.keys()

<Out> ['_dh', '__', 'dill', '_15', '__builtin__', '_i32', '_30', '_16', '_i15', quit', '_34', '_i11', '_i9', '_i8', '_i7', '_i6', '_i5', '_i4', '_i3', '_i2', _i1', '__package__', 'exit', 'get_ipython', '_i', '_i29', '_i26', '_i17', _i24', _i14', '_i22', '__doc__', '_i20', '_i16', '_i21', '_18', '_11', '_i34', __builtins__', '_ih', '_i28', 'sys', '_20', '_i27', '__name__', '___', '_i33', _', '_sh', '_i25', '_29', '_32', '_22', 'func_dict_loaded', '_i23', '_i13', _i12', '_iii', '_i10', '_13', '_12', '_ii', 'In', '_i31', '_i30', '_i19', _i18', _i35', '_oh', 'Out']

Без доступа к словарю функций! Что мне нужно сделать, чтобы получить желаемый результат?


person MoMiJi    schedule 30.12.2017    source источник
comment
Отличный пост для нового пользователя!   -  person Noah Cristino    schedule 30.12.2017
comment
Спасибо @ иσαнcяişтiпσ!   -  person MoMiJi    schedule 30.12.2017


Ответы (2)


Возможно, мне что-то здесь не хватает, но я ожидал, что функции будут в func_dict_loaded.items(), и если вы хотите вызвать функцию _i7, вы делаете func_dict_loaded['_i7']().

Я пытался воспроизвести вашу проблему, но избегал манипуляций с globals(). Это небезопасно. Вам не нужно делать это, чтобы определять функции, вы можете просто создать свои собственные.

Итак, за один сеанс:

>>> import dill
>>> def myfunc():
        print("Hello world")
>>> mydict = {"myfunc": myfunc}
>>> with open (r"C:\..etc..\Temp\dict.p","wb") as f:
        dill.dump(mydict,f)

И в другом сеансе:

>>> import dill
>>> mydict=dill.load(open (r"C:\..etc..\Temp\dict.p","rb"))
>>> mydict
{'myfunc': <function myfunc at 0x000001FC9F4C69D8>}
>>> mydict["myfunc"]()
Hello world

Как видите, если довести до такого уровня простоты, все работает.

person BoarGules    schedule 30.12.2017
comment
Привет, @BoarGules, спасибо за предложение. Я пробовал func_dict_loaded.items(), значения представляют собой просто множество строк, либо тех же ключей, вложенных в другой ключ, либо путей к файлам к модулям. Я не вижу ни одного из элементов, которые хотел бы включить, например func_dict, Interp1dPicklable, PolyValPicklable. Думаю, я неправильно его замариновал, но не вижу, где это могло произойти. - person MoMiJi; 31.12.2017

Я вроде исправил, вот как:

при сбросе словаря функций вместо:

dill.dump(globals(), f)

Я использовал:

dill.settings['recurse'] = True

with open('./Data/function_dict.p', 'wb') as f:
    dill.dump([dill, interp1d, Interp1dPicklable, PolyValPicklable, func_dict], f)
f.close()

Первая строка - это совет, который я нашел здесь

Затем, когда я загружаю .p файл, я вызываю:

dill.settings['recurse'] = True

func_dict_loaded = dill.load(open("./Data/function_dict.p", "rb"))

(Не уверен, нужна ли там первая строка, но, похоже, это не причинит никакого вреда.)

Потом:

func_dict_loaded[-1]

Возвращает func_dict (обратите внимание на порядок списка при сбросе).

Тогда я могу использовать

func_dict_loaded[-1]['func1'](x)

чтобы вернуть результат func_1 для переменной x.

Спасибо всем, кто смотрел и комментировал / отвечал, я надеюсь, что это может помочь кому-то еще с аналогичной проблемой в будущем!

person MoMiJi    schedule 31.12.2017