2010-04-12 7 views

Répondre

4

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

+0

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

+0

Le projet fyi a été transféré à github: https://github.com/IronLanguages/main/tree/ipy-2.7-maint/Languages/IronPython/Samples/ClrType –

2

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.

+0

-je utiliser binaire sérialisation .NET. – Pablo

+0

merci pour la réponse, jetez un oeil à mon deuxième poste si cela vous intéresse :) – Pablo

Questions connexes