序列化继承自CLR类型的IronPython对象

5 投票
2 回答
1670 浏览
提问于 2025-04-16 04:16

这个问题可能有点奇怪,但有没有什么可靠的方法可以把扩展了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 个回答

2

我不知道这是否是你想要的,但你可以考虑使用Python版本的protobuf(在这里)?不过我没有专门在ironpython上测试过。这个方法还有个好处,就是有C#的实现可以参考,这样就能保持跨平台的兼容性。如果有可能的话,我希望能让protobuf-net支持DLR类型,但这是一项大工程。

顺便提一下,我个人建议使用专门的DTO类型,而不是试图扩展内置类型。

1

引用自 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 类型。

我没有尝试过,但也许你可以通过手动序列化来解决这个问题,使用 序列化代理

撰写回答