472,355 Members | 1,856 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,355 software developers and data experts.

Why can't you pickle instancemethods?

Why can pickle serialize references to functions, but not methods?

Pickling a function serializes the function name, but pickling a
staticmethod, classmethod, or instancemethod generates an error. In
these cases, pickle knows the instance or class, and the method, so
what's the problem? Pickle doesn't serialize code objects, so why can't
it serialize the name as it does for functions? Is this one of those
features that's feasible, but not useful, so no one's ever gotten
around to implementing it?

Regards,
Chris
>>import pickle

def somefunc():
.... return 1
....
>>class Functions(object):
.... @staticmethod
.... def somefunc():
.... return 1
....
>>class Foo(object):
.... pass
....
>>f = Foo()
f.value = somefunc
print pickle.dumps(f)
ccopy_reg
_reconstructor
p0
(c__main__
Foo
p1
c__builtin__
object
p2
Ntp3
Rp4
(dp5
S'value'
p6
c__main__
somefunc
p7
sb.
>>>
f.value = Functions.somefunc
print pickle.dumps(f)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "C:\Program Files\Python24\lib\pickle.py", line 1386, in dumps
Pickler(file, protocol, bin).dump(obj)
File "C:\Program Files\Python24\lib\pickle.py", line 231, in dump
self.save(obj)
File "C:\Program Files\Python24\lib\pickle.py", line 338, in save
self.save_reduce(obj=obj, *rv)
File "C:\Program Files\Python24\lib\pickle.py", line 433, in
save_reduce
save(state)
File "C:\Program Files\Python24\lib\pickle.py", line 293, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Program Files\Python24\lib\pickle.py", line 663, in
save_dict
self._batch_setitems(obj.iteritems())
File "C:\Program Files\Python24\lib\pickle.py", line 677, in
_batch_setitems
save(v)
File "C:\Program Files\Python24\lib\pickle.py", line 293, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Program Files\Python24\lib\pickle.py", line 765, in
save_global
raise PicklingError(
pickle.PicklingError: Can't pickle <function somefunc at 0x009EC5F0>:
it's not the same object as __
main__.somefunc

Oct 20 '06 #1
5 91290
Chris wrote:
Why can pickle serialize references to functions, but not methods?

Pickling a function serializes the function name, but pickling a
staticmethod, classmethod, or instancemethod generates an error. In
these cases, pickle knows the instance or class, and the method, so
what's the problem? Pickle doesn't serialize code objects, so why can't
it serialize the name as it does for functions? Is this one of those
features that's feasible, but not useful, so no one's ever gotten
around to implementing it?
I have often wondered this myself. I'm convinced that it would in fact
be useful -- more than once I've written a program that has lots of
objects with function pointers, and where it was inconvenient that the
method pointers could not be pickled. One compromise that I have used
before is to write a class such as:

class InstanceMethodSet(object):
def __init__(self,methods):
self.methods = set(methods)
def __getstate__(self):
return [(method.im_self, method.im_func.func_name)
for method in self.method]
def __setstate__(self,state):
self.methods = set(getattr(obj,name) for obj,name in state)

Obviously, this particular example is crude and not terribly robust,
but it seems to do the job -- it effectively lets you pickle a set of
instance method pointers. I don't know of any reason why instance
methods (or class or static methods) couldn't be pickled directly,
unless perhaps there exists some kind of pathological corner case that
would create Badness?

-Matt

Oct 20 '06 #2
At Friday 20/10/2006 18:33, Chris wrote:
>Why can pickle serialize references to functions, but not methods?
Because all references must be globally accessible.
>Pickling a function serializes the function name, but pickling a
staticmethod, classmethod, or instancemethod generates an error. In
these cases, pickle knows the instance or class, and the method, so
what's the problem? Pickle doesn't serialize code objects, so why can't
it serialize the name as it does for functions? Is this one of those
features that's feasible, but not useful, so no one's ever gotten
around to implementing it?
Well, it's not so common to take a method from one class and glue it
into an *instance* of another class...
(Note that if you copy&paste a method from one *class* into another
*class*, pickle works OK, as long as in the unpickling environment
you rebuild your classes the same way)

For static methods there is no way you can retrieve a globally usable
name (like 'Functions.somefunc' in your example) - at least I don't
know how to do it, they appear to have lost any reference to the
defining class.
For class methods you can build such reference using im_self and
im_func.func_name
For instance methods use im_class and im_func.func_name
Then define your own __getstate__ and __setstate__.
--
Gabriel Genellina
Softlab SRL

__________________________________________________
Correo Yahoo!
Espacio para todos tus mensajes, antivirus y antispam ˇgratis!
ˇAbrí tu cuenta ya! - http://correo.yahoo.com.ar
Oct 20 '06 #3
md******@gmail.com wrote:
Chris wrote:
Why can pickle serialize references to functions, but not methods?

Pickling a function serializes the function name, but pickling a
staticmethod, classmethod, or instancemethod generates an error. In
these cases, pickle knows the instance or class, and the method, so
what's the problem? Pickle doesn't serialize code objects, so why can't
it serialize the name as it does for functions? Is this one of those
features that's feasible, but not useful, so no one's ever gotten
around to implementing it?

I have often wondered this myself. I'm convinced that it would in fact
be useful -- more than once I've written a program that has lots of
objects with function pointers, and where it was inconvenient that the
method pointers could not be pickled. One compromise that I have used
before is to write a class such as:

class InstanceMethodSet(object):
def __init__(self,methods):
self.methods = set(methods)
def __getstate__(self):
return [(method.im_self, method.im_func.func_name)
for method in self.method]
def __setstate__(self,state):
self.methods = set(getattr(obj,name) for obj,name in state)

Obviously, this particular example is crude and not terribly robust,
but it seems to do the job -- it effectively lets you pickle a set of
instance method pointers. I don't know of any reason why instance
methods (or class or static methods) couldn't be pickled directly,
unless perhaps there exists some kind of pathological corner case that
would create Badness?

-Matt
Thanks, that's quite clever. Although I think you'd still have to
explicitly specify im_self for staticmethods. I could imagine a similar
callable proxy that simply removes the direct method reference from the
equation:

class MethodProxy(object):
def __init__(self, obj, method):
self.obj = obj
if isinstance(method, basestring):
self.methodName = method
else:
assert callable(method)
self.methodName = method.func_name
def __call__(self, *args, **kwargs):
return getattr(self.obj, self.methodName)(*args, **kwargs)

picklableMethod = MethodProxy(someObj, someObj.method)

Oct 20 '06 #4
Chris wrote:
Why can pickle serialize references to functions, but not methods?
Here's the recipe I use::

def _pickle_method(method):
func_name = method.im_func.__name__
obj = method.im_self
cls = method.im_class
return _unpickle_method, (func_name, obj, cls)

def _unpickle_method(func_name, obj, cls):
for cls in cls.mro():
try:
func = cls.__dict__[func_name]
except KeyError:
pass
else:
break
return func.__get__(obj, cls)

import copy_reg
import types
copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)

There may be some special cases where this fails, but I haven't run into
them yet.

STeVe
Oct 21 '06 #5
Steven Bethard wrote:
Here's the recipe I use::

[...]

There may be some special cases where this fails, but I haven't run into
them yet.
Wow, that's a really nice recipe; I didn't even know about the copy_reg
module. I'll have to start using that.

I did notice one failure mode, however--it doesn't work with methods
named __foo because im_func.__name__ contains the *unmangled* version
of the function name, so when you try to unpickle the method, the try
statement never succeeds and you get an UnboundLocalError on func.

The good news is that I think it can be fixed by mangling the name
manually in _pickle_method(), like so:

def _pickle_method(method):
func_name = method.im_func.__name__
obj = method.im_self
cls = method.im_class
if func_name.startswith('__') and not func_name.endswith('__'):
cls_name = cls.__name__.lstrip('_')
if cls_name: func_name = '_' + cls_name + func_name
return _unpickle_method, (func_name, obj, cls)

Nov 11 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Tracy Ruggles | last post by:
>>> sys.platform, sys.version ('freebsd4', '2.2.3 (#2, Nov 17 2003, 17:03:14) \n]') I've poured through pickle.py (line 525) and see where the PicklingError is being raised, but I can't figure...
2
by: Jane Austine | last post by:
Hi. class A: def __init__(self,tick): if tick: self.foo=self.bar else: self.foo=self.bur def bar(self): print 'bar'
0
by: Mike P. | last post by:
Hi all, I'm working on a simulation (can be considered a game) in Python where I want to be able to dump the simulation state to a file and be able to load it up later. I have used the standard...
6
by: Jim Lewis | last post by:
Pickling an instance of a class, gives "can't pickle instancemethod objects". What does this mean? How do I find the class method creating the problem?
10
by: crystalattice | last post by:
I'm creating an RPG for experience and practice. I've finished a character creation module and I'm trying to figure out how to get the file I/O to work. I've read through the python newsgroup...
3
by: fizilla | last post by:
Hello all! I have the following weird problem and since I am new to Python I somehow cannot figure out an elegant solution. The problem reduces to the following question: How to pickle a...
2
by: Michele Simionato | last post by:
Can somebody explain what's happening with the following script? $ echo example.py import pickle class Example(object): def __init__(self, obj, registry): self._obj = obj self._registry =...
10
by: est | last post by:
>>import md5 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python25\lib\pickle.py", line 1366, in dumps Pickler(file, protocol).dump(obj) File...
1
by: IceMan85 | last post by:
Hi to all, I have spent the whole morning trying, with no success to pickle an object that I have created. The error that I get is : Can't pickle 'SRE_Match' object: <_sre.SRE_Match object at...
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was proposed, which integrated multiple engines and...
2
by: Matthew3360 | last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it so the python app could use a http request to get...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
0
Oralloy
by: Oralloy | last post by:
Hello Folks, I am trying to hook up a CPU which I designed using SystemC to I/O pins on an FPGA. My problem (spelled failure) is with the synthesis of my design into a bitstream, not the C++...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS starter kit that's not only easy to use but also...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.