将IronPython类标记为可序列化

时间:2010-04-12 18:59:00

标签: .net ironpython

是否可以在IronPython中执行此操作,如果是,如何执行此操作?

2 个答案:

答案 0 :(得分:4)

IronPython开发人员给了我这个例子,用于在python类上添加.NET属性,比如Serializable。

http://ironpython.codeplex.com/releases/view/36280#DownloadId=116513

答案 1 :(得分:2)

Python的序列化版本是Pickling(我相信)。 我不认为一个类必须标记为可序列化。

所以你必须这样做:

import clr clr.AddReference( “IronPython.Modules”)

来自IronPython.Modules的

导入PythonPickle

stored = PythonPickle.dumps(“ASDF”) recover = PythonPickle.loads(存储)#recovered是“ASDF”


嗯,你绝对可以将其标记为可序列化的...... 我调查了here

我能够使它可以序列化,以便BinaryFormatter接受并序列化它,但反序列化是不可能的:

from System.IO import File
from System.Runtime.Serialization.Formatters.Binary import BinaryFormatter #whew
from System.Runtime.Serialization import ISerializable, SerializationException
from System import SerializableAttribute, ObsoleteAttribute
from System.Reflection.Emit import OpCodes, CustomAttributeBuilder
from System.Security.Permissions import *
import clr
clr.AddReference("Microsoft.Dynamic")
clr.AddReference("IronPython")
from Microsoft.Scripting.Generation import Snippets

class ClrTypeMetaclass(type):
  def __clrtype__(cls):
    baseType = super(ClrTypeMetaclass, cls).__clrtype__()
    typename = cls._clrnamespace + "." + cls.__name__ \
                 if hasattr(cls, "_clrnamespace") \
                 else cls.__name__
    typegen = Snippets.Shared.DefineType(typename, baseType, True, False)
    typebld = typegen.TypeBuilder

    for ctor in baseType.GetConstructors(): 
      ctorparams = ctor.GetParameters()
      ctorbld = typebld.DefineConstructor(
                  ctor.Attributes,
                  ctor.CallingConvention,
                  tuple([p.ParameterType for p in ctorparams]))
      ilgen = ctorbld.GetILGenerator()
      ilgen.Emit(OpCodes.Ldarg, 0)
      for index in range(len(ctorparams)):
        ilgen.Emit(OpCodes.Ldarg, index + 1)
      ilgen.Emit(OpCodes.Call, ctor)
      ilgen.Emit(OpCodes.Ret)

    if hasattr(cls, '_clrclassattribs'):
      for cab in cls._clrclassattribs:
        typebld.SetCustomAttribute(cab)

    return typebld.CreateType()

def make_cab(attrib_type, *args, **kwds):
  clrtype = clr.GetClrType(attrib_type)
  argtypes = tuple(map(lambda x:clr.GetClrType(type(x)), args))
  ci = clrtype.GetConstructor(argtypes)

  props = ([],[])
  fields = ([],[])

  for kwd in kwds:
    pi = clrtype.GetProperty(kwd)
    if pi is not None:
      props[0].append(pi)
      props[1].append(kwds[kwd])
    else:
      fi = clrtype.GetField(kwd)
      if fi is not None:
        fields[0].append(fi)
        fields[1].append(kwds[kwd])
      else:
        raise Exception, "No %s Member found on %s" % (kwd, clrtype.Name)

  return CustomAttributeBuilder(ci, args, 
    tuple(props[0]), tuple(props[1]), 
    tuple(fields[0]), tuple(fields[1]))

def cab_builder(attrib_type):
  return lambda *args, **kwds:make_cab(attrib_type, *args, **kwds)

Serializable = cab_builder(SerializableAttribute)

class Applesauce(ISerializable):
    __metaclass__ = ClrTypeMetaclass
    _clrnamespace = "Yummy.Yum.Food"
    _clrclassattribs = [Serializable()]
    def __init__(self):
        self.sweetness = 10
    def GetObjectData(self,info,context):
        info.AddValue("sweetness",10)
binformatter = BinaryFormatter()
output = File.Create("applesauce.dat")
binformatter.Serialize(output,Applesauce()) 
output.Close()

当然,输出文件只有序列化的“sweetness”属性,因为它在GetObjectData方法中作为info.AddValue(...)

所以现在,我认为可以肯定地认为在纯IronPython中将其标记为可序列化是不可能的。