序列化 importlib 导入的字典时无法 pickle/dill SwigPyObject
Can't pickle/dill SwigPyObject when serializing dict imoprted by importlib
我尝试序列化(dill)一个列表,其中包含嵌套在 dict 中的 dill-able 对象。 dict 本身使用 importlib 导入到我的主脚本中。调用 dill.dump()
引发 TypeError: can't pickle SwigPyObject objects
。这是我设法重现错误以获得更多见解的一些代码。
some_config.py 位于 config/some_config.py:
from tensorflow.keras.optimizers import SGD
from app.feature_building import Feature
config = {
"optimizer": SGD(lr=0.001),
"features": [
Feature('method', lambda v: v + 1)
],
}
这是导入配置并尝试钻取配置的代码["features"]:
import dill
import importlib.util
from config.some_config import config
spec = importlib.util.spec_from_file_location(undillable.config,"config/some_config.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
undillable_config = module.config
# Works prefectly fine
with open("dillable_config.pkl", "wb") as f:
dill.dump(config["features"], f)
# Raises TypeError: can't pickle SwigPyObject objects
with open("undillable_config.pkl", "wb") as f:
dill.dump(undillable_config["features"], f)
现在让我感到疑惑的部分是:当使用 importlib 导入 config-dict 时它会引发错误,经过一些调试后我发现不仅 config["features"]
而且 config["optimizer"]
都会被删除。然而,使用正常的 import
似乎可行,它只会尝试 dill config["features"]
所以我的问题是,如果 dill 是由 importlib 而不仅仅是功能列表导入的,为什么 dill 会尝试序列化整个 dict 以及如何修复这个错误?
阅读 this question 的答案后,我设法通过避免 importlib 并使用 __import__
导入配置来让它工作。
filename = "config/some_config.py"
dir_name = os.path.dirname(filename)
if dir_name not in sys.path:
sys.path.append(dir_name)
file = os.path.splitext(os.path.basename(filename))[0]
config_module = __import__(file)
# Works prefectly fine now
with open("dillable_config.pkl", "wb") as f:
dill.dump(config_module.config["features"], f)
我尝试序列化(dill)一个列表,其中包含嵌套在 dict 中的 dill-able 对象。 dict 本身使用 importlib 导入到我的主脚本中。调用 dill.dump()
引发 TypeError: can't pickle SwigPyObject objects
。这是我设法重现错误以获得更多见解的一些代码。
some_config.py 位于 config/some_config.py:
from tensorflow.keras.optimizers import SGD
from app.feature_building import Feature
config = {
"optimizer": SGD(lr=0.001),
"features": [
Feature('method', lambda v: v + 1)
],
}
这是导入配置并尝试钻取配置的代码["features"]:
import dill
import importlib.util
from config.some_config import config
spec = importlib.util.spec_from_file_location(undillable.config,"config/some_config.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
undillable_config = module.config
# Works prefectly fine
with open("dillable_config.pkl", "wb") as f:
dill.dump(config["features"], f)
# Raises TypeError: can't pickle SwigPyObject objects
with open("undillable_config.pkl", "wb") as f:
dill.dump(undillable_config["features"], f)
现在让我感到疑惑的部分是:当使用 importlib 导入 config-dict 时它会引发错误,经过一些调试后我发现不仅 config["features"]
而且 config["optimizer"]
都会被删除。然而,使用正常的 import
似乎可行,它只会尝试 dill config["features"]
所以我的问题是,如果 dill 是由 importlib 而不仅仅是功能列表导入的,为什么 dill 会尝试序列化整个 dict 以及如何修复这个错误?
阅读 this question 的答案后,我设法通过避免 importlib 并使用 __import__
导入配置来让它工作。
filename = "config/some_config.py"
dir_name = os.path.dirname(filename)
if dir_name not in sys.path:
sys.path.append(dir_name)
file = os.path.splitext(os.path.basename(filename))[0]
config_module = __import__(file)
# Works prefectly fine now
with open("dillable_config.pkl", "wb") as f:
dill.dump(config_module.config["features"], f)