est-il possible de le faire dans IronPython et si oui, comment?marquage IronPython classe comme sérialisable
Répondre
Cet exemple m'a été donné par l'un des développeurs IronPython, pour l'ajout d'attributs .NET sur des classes python, telles que Serializable.
http://ironpython.codeplex.com/releases/view/36280#DownloadId=116513
La version de Python de sérialisation est Pickling (je crois). Je ne pense pas qu'une classe doive être marquée sérialisable.
Vous devez faire ceci:
importation clr clr.AddReference ("IronPython.Modules")
de IronPython.Modules importer PythonPickle
stockés = PythonPickle.dumps ("ASDF «) récupéré = PythonPickle.loads (stocké) #recovered est "ASDF"
Eh bien, vous pouvez defini marquer un Tely comme sérialisable ... Je regardais dans here
et j'ai pu faire de tri sérialisable afin que le BinaryFormatter considérera et sérialisation, mais désérialisation est impossible:
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()
bien sûr, le fichier de sortie n'avait la « douceur » attribut sérialisé parce qu'il était dans la méthode GetObjectData comme info.AddValue (...)
donc maintenant, je pense qu'il est sûr de conclure qu'il est impossible de marquez-le comme sérialisable en IronPython pur.
Je pense que le projet CodePlex a été écrit par DevHawk (le même développeur que la solution dans la réponse de @ jcao219) - il vaut donc la peine de lire son [explication] (http://devhawk.net/tag/__clrtype__). Cela demande des efforts, mais il y a beaucoup de bonnes choses là-dedans. – Wesley
Le projet fyi a été transféré à github: https://github.com/IronLanguages/main/tree/ipy-2.7-maint/Languages/IronPython/Samples/ClrType –