маркировка класса IronPython как сериализуемого - PullRequest
3 голосов
/ 12 апреля 2010

возможно ли это сделать в IronPython, и если да, то как?

Ответы [ 2 ]

4 голосов
/ 14 апреля 2010

Мне привел этот пример один из разработчиков IronPython для добавления атрибутов .NET в классы Python, таких как Serializable.

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

2 голосов
/ 14 апреля 2010

Версия сериализации Python - Pickling (я полагаю). Я не думаю, что класс должен быть помечен как сериализуемый.

Итак, вы должны сделать это:

импорт clr clr.AddReference ( "IronPython.Modules")

из IronPython. Импорт модулей PythonPickle

сохранен = PythonPickle.dumps ("ASDF") recovered = PythonPickle.loads (сохранено) #recovered "ASDF"


Ну, вы определенно можете пометить один как сериализуемый ... Я посмотрел в здесь

и я смог сделать его своего рода сериализуемым, чтобы 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()

конечно, в выходном файле сериализуется только атрибут "сладость", поскольку он был в методе GetObjectData как info.AddValue (...)

Так что сейчас, я думаю, можно с уверенностью заключить, что невозможно пометить его как сериализуемый в чистом IronPython.

...