Object serialization: transfer from a to b (non-implemented code on b)

Andreas Löscher andreas.loescher at s2005.tu-chemnitz.de
Wed Apr 14 13:47:40 CEST 2010


Am Mittwoch, den 14.04.2010, 12:37 +0200 schrieb Gabriel Rossetti:
> Andreas Löscher wrote:
> > Am Mittwoch, den 14.04.2010, 11:33 +0200 schrieb Gabriel Rossetti:
> >   
> >> Paul Rubin wrote:
> >>     
> >>> Gabriel Rossetti <gabriel.rossetti at arimaz.com> writes:
> >>>   
> >>>       
> >>>> I am trying to serialize a function, class, etc and transfer it
> >>>>     
> >>>>         
> >>> You mean the actual code?  You have to use marshal rather than pickle,
> >>> the Python versions have to be the same at both ends, and you better
> >>> have some kind of authenticated transport to stop malicious code from
> >>> getting accepted and run by the receiving end.
> >>>   
> >>>       
> >> Yes, but I wasn't able to marshal/unmarshal them correctly as shown in 
> >> my examples
> >>     
> >
> > The marshal module can be used to dump the Code of an Function (or
> > anything else), like you have done. If you have the Code, you can
> > reconstruct the function.
> >
> >   
> >>>> import types
> >>>> import marshal
> >>>> def a(): pass
> >>>>         
> > ... 
> >   
> >>>> s=marshal.dumps(a.__code__)
> >>>> f=types.FunctionType(marshal.loads(s), {})
> >>>> f
> >>>>         
> > <function a at 0x7f6308a66de8>
> >
> > The second parameter is the global scoop of the function.
> >
> > If you want to marshal a class, things get a little more complicated,
> > because these consist of many code objects and you also need the code 
> > to assemble them together.
> >
> > There are two easy ways I can think of right now:
> >
> > 1.
> > Send the string of the code you want to transfer:
> >   
> >>>> s="""class A: pass"""
> >>>>         
> >
> > and then:
> >   
> >>>> exec(s) in globals()
> >>>>         
> >
> > 2.
> > Encapsule the stuff you want to send in a function.
> >
> >
> > Best,
> > Andreas
> >
> >   
> Thanks Andreas, I'll give that a try. I didn't really want to do the 
> string method which is why I was trying to serialize.
> 
> best,
> Gabriel

You can compile the string befor you send it in an code object. This way
you also don't need to compile it twice if you execute ist two times. 

>>> s="""class A: pass"""
>>> co=compile(s, "foo.py", "exec")

>>> exec(marshal.loads(marshal.dumps(co))) in globals()

But be aware, that the string method may be the most save method for
doing this. Python is not ByteCode compatible between it's versions.
But if I understand you right, this is not an issue for you.

Best,
Andreas




More information about the Python-list mailing list