#python #python-3.x #pickle
#python #python-3.x #настройка
Вопрос:
Мне нужно назначить модуль и класс ключу словаря. Затем настройте этот словарь в файл. Затем позже загрузите файл pkl, затем импортируйте и создайте экземпляр класса на основе этого значения ключа словаря.
Я пробовал это:
import module_example
from module_example import ClassExample
dictionary = {'module': module_example, 'class': ClassExample)
Тем не менее, он не сохранит ссылку на module_exmaple.py в файле pkl.
Я попробовал обходной путь использования строки вместо имени модуля и класса. Но это приведет к беспорядку, если имя модуля будет переработано или местоположение будет изменено в будущем.
Есть ли в любом случае возможность сделать это напрямую? Каким-то образом сохраните ссылку на модуль и класс в словаре, а затем импортируйте и создайте экземпляр на основе этой ссылки?
Ответ №1:
Это работает для одного класса. Если вы хотите сделать это в нескольких модулях и классах, вы можете расширить следующий код.
module_class_writer.py
import module_example
from module_example import ClassExample
included_module = ["module_example"]
d = {}
for name, val in globals().items():
if name in included_module:
if "__module__" in dir(val):
d["module"] = val.__module__
d["class"] = name
#d = {'module': module_example, 'class': ClassExample}
import pickle
filehandler = open("imports.pkl","wb")
pickle.dump(d, filehandler)
filehandler.close()
module_class_reader.py
import pickle
filehandler = open("imports.pkl",'rb')
d = pickle.load(filehandler)
filehandler.close()
def reload_class(module_name, class_name):
mod = __import__(module_name, fromlist=[class_name])
reload(mod)
return getattr(mod, class_name)
if "class" in d and "module" in d:
reload(__import__(d["module"]))
ClassExample = reload_class(d["module"], d["class"])
Ответ №2:
Если вы хотите, чтобы необработанный класс был точно таким же объектом, который был изменен, вам придется сохранить код класса (используя внешнюю библиотеку, такую, например, как dill).
В противном случае, в стандартном pickle невозможно сохранить ссылку на класс, который «переживет» рефакторинг.
Комментарии:
1. Мне не нужен один и тот же объект. Но мне нужна ссылка на класс. Чтобы я мог создать экземпляр нового объекта на основе этой ссылки. Если имя этого класса и / или местоположение будет переработано, я бы хотел, чтобы ссылка также отражала это. Каким-либо образом это можно сделать?
2. @Emily: Python никак не сможет определить, что новый класс и старый класс являются «одним и тем же классом» после такого рефакторинга.