如何使Python反序列化函数可从另一个模块使用?
我有一些序列化和反序列化代码,它们在一个模块内(以及在我关心的类的范围内)运行良好。例如 但是,如果我在另一个模块中定义一个类,并在那里导入如何使Python反序列化函数可从另一个模块使用?,python,serialization,scope,Python,Serialization,Scope,我有一些序列化和反序列化代码,它们在一个模块内(以及在我关心的类的范围内)运行良好。例如 但是,如果我在另一个模块中定义一个类,并在那里导入序列化和反序列化,则序列化可以工作,但反序列化有问题。反序列化函数不“知道”其他模块中的类定义,无法实例化实例 到目前为止,我使用了两种不同的方法来解决这个问题。一种是将globals()和locals()传递到反序列化,然后调用eval。另一个调用方传入\uuu name\uu和反序列化调用检查.getmembers(sys.modules[passedN
序列化
和反序列化
,则序列化可以工作,但反序列化有问题。反序列化函数不“知道”其他模块中的类定义,无法实例化实例
到目前为止,我使用了两种不同的方法来解决这个问题。一种是将globals()
和locals()
传递到反序列化
,然后调用eval
。另一个调用方传入\uuu name\uu
和反序列化调用检查.getmembers(sys.modules[passedName])
。我还可能需要将每个可序列化类注册到反序列化可见的列表中
但是,我不喜欢这些变通办法。有更好的办法吗
(如果有必要的话,我需要使用Python 2.7,因为这就是我们目前的工作。)
补充:我已经基于ABCMeta
元类编写了一个版本的“在某个列表中注册每个可序列化类”策略,看起来并不太可怕。它确实涉及到查看注册表,感觉有点不对劲。上一次测试中可能存在一个问题:
assert( obj == deserialize( serialize( obj ) ) )
这些对象将“实际上相等”,但会有两个相同对象的不同实例
类,所有成员都相同
您可以通过询问对象的id(obj)
值来检查它,您将得到不同的值
要解决这一问题(如果您希望允许两个不同的实例相等),请将\uuuueq\uuuuu
添加到
上课
下面是我定义此类类的尝试,并添加了使用JSON的序列化
和反序列化
一串要显示,序列化
和反序列化
函数可能位于类以外的模块中,
它们被分为不同的模块:
文件教室.py
:
测试代码:test\u ser.py
以下是我的测试(使用pytest
)。我将其放入文件test\u ser.py
:
import pytest
@pytest.fixture
def a_instance():
from serdeser import A
return A(11, 12)
@pytest.fixture
def a_serialized(a_instance):
from serdeser import serialize
return serialize(a_instance)
@pytest.fixture
def b_instance():
from serdeser import B
return B(88, 99)
@pytest.fixture
def b_serialized(b_instance):
from serdeser import serialize
return serialize(b_instance)
def test_A(a_instance, a_serialized):
from serdeser import deserialize
assert a_instance == deserialize(a_serialized)
def test_B(b_instance, b_serialized):
from serdeser import deserialize
assert b_instance == deserialize(b_serialized)
您应安装pytest
:
$ pip install pytest
要运行测试(并假设文件serdeser.py
和school.py
处于
同一目录:
$ py.test -sv test_ser.py (env: stack)
========================================= test session starts =========================================
platform linux2 -- Python 2.7.9 -- py-1.4.30 -- pytest-2.7.2 -- /home/javl/.virtualenvs/stack/bin/python2
rootdir: /home/javl/sandbox/stack, inifile:
collected 2 items
test_ser.py::test_A PASSED
test_ser.py::test_B PASSED
====================================== 2 passed in 0.01 seconds =======================================
一切都交给我了
如果从当前目录导入serdesr
模块时遇到问题,请使用:
$ EXPORT PYTHONPATH="."
在我的测试中,我从不将serdeser
中的任何内容导入全局范围,只导入测试用例的范围
功能
导入函数反序列化
时不应出现问题,因为它们具有类A
的知识
在同一个模块中定义。是否有理由不使用pickle
或joblib
或其他标准序列化工具?是的。我试图保持问题的直接性,因此没有详细说明情况。其中之一是我正在构建一个现有的基于文本的序列化方案。它对或者我们的结果字符串是可读的。但是现有的方案对我来说太有限了,因为它主要局限于基本类型的元组。谢谢。关于\uuuuuueq\uuuuu
和类似的内容,你是对的。我一直在使用的类都有它们,但我会将它们添加到任何新的类中。但是我确实需要反序列化才能使用classe在不同的模块中定义了。@Uncorrelated我已将类定义分为文件classification.py
。因此serialize
和deserialize
与类在不同的模块中,并且它们仍然有效。
$ pip install pytest
$ py.test -sv test_ser.py (env: stack)
========================================= test session starts =========================================
platform linux2 -- Python 2.7.9 -- py-1.4.30 -- pytest-2.7.2 -- /home/javl/.virtualenvs/stack/bin/python2
rootdir: /home/javl/sandbox/stack, inifile:
collected 2 items
test_ser.py::test_A PASSED
test_ser.py::test_B PASSED
====================================== 2 passed in 0.01 seconds =======================================
$ EXPORT PYTHONPATH="."