2010-04-12 85 views

回答

4

我被一個IronPython開發人員給出了這個例子,用於在python類(如Serializable)上添加.NET屬性。

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

+0

我認爲CodePlex項目是由DevHawk(與@ jcao219答案中的解決方案相同的開發人員)編寫的 - 所以它絕對值得通讀他的[解釋](http://devhawk.net/tag/__clrtype__)。它需要一些努力,但是那裏有很多好東西。 – Wesley 2011-10-01 16:08:07

+0

fyi項目已移至github:https://github.com/IronLanguages/main/tree/ipy-2.7-maint/Languages/IronPython/Samples/ClrType – 2017-05-24 07:24:54

2

Python的序列化版本是Pickling(我相信)。 我不認爲一個類必須被標記爲可序列化。

所以,你必須這樣做:

進口CLR clr.AddReference( 「IronPython.Modules」)

從IronPython.Modules導入PythonPickle

存儲= PythonPickle.dumps(「ASDF 「) 恢復PythonPickle.loads(存儲)#recovered =是 「ASDF」


那麼,你可以defini tely一個標記爲可序列化...... 我看着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() 

當然,輸出文件只有「甜味」屬性序列化,因爲它在GetObjectData方法中,因爲它是info.AddValue(...)

因此,現在我認爲可以安全地得出結論:將其標記爲可在純IronPython中進行序列化。

+0

我需要使用.NET的二進制序列化。 – Pablo 2010-04-14 00:24:11

+0

感謝您的回覆,看看我的第二篇文章,如果這有利於你:) – Pablo 2010-04-14 11:20:09