序列化继承自CLR类型的IronPython对象
这个问题可能有点奇怪,但有没有什么可靠的方法可以把扩展了CLR类型的IronPython对象进行序列化呢?
举个例子:
class Foo(System.Collections.Generic.List[str]):
def Test(self):
print "test!"
System.Collections.Generic.List<string>
可以用Pickle进行序列化,因为它实现了ISerializable
接口。但是,生成的可序列化CLR类型的子类似乎不行,当我运行pickle.dumps(Foo())
时,会出现ImportError: No module named Generic in mscorlib, Version=4
的错误。
此外,运行通常的Formatter.Serialize(stream, object)
也会让我遇到:
SystemError: Type 'IronPython.NewTypes.System.Collections.Generic.List`1_4$4' in Assembly Snippets.scripting, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
在嵌入式C#环境中,如何实现IronPython对象的序列化呢?
2 个回答
我不知道这是否是你想要的,但你可以考虑使用Python版本的protobuf(在这里)?不过我没有专门在ironpython上测试过。这个方法还有个好处,就是有C#的实现可以参考,这样就能保持跨平台的兼容性。如果有可能的话,我希望能让protobuf-net支持DLR类型,但这是一项大工程。
顺便提一下,我个人建议使用专门的DTO类型,而不是试图扩展内置类型。
引用自 clrtype 元类
IronPython 目前不支持基于反射的 API 或自定义属性,因为 IronPython 不会为每个 Python 类生成一个自定义的 CLR 类型。相反,它通常会在多个 Python 类之间共享一个单一的 CLR 类型。例如,下面这三个 Python 类都共享一个相同的基础 CLR 类型。
class shop(object):
pass
class cheese_shop(shop):
def have_cheese(self, cheese_type):
return False
class argument_clinic(object):
def is_right_room(self, room=12):
return "I've told you once"
import clr
print clr.GetClrType(shop).FullName
print clr.GetClrType(cheese_shop).FullName
print clr.GetClrType(argument_clinic).FullName
尽管 cheese_shop 继承自 shop,argument_clinic 继承自 object,但这三个类仍然共享同一个基础 CLR 类型。
我没有尝试过,但也许你可以通过手动序列化来解决这个问题,使用 序列化代理。