[Chicago] problem with __getstate__

Massimo Di Pierro mdipierro at cs.depaul.edu
Mon May 19 06:50:33 CEST 2008


__getstate__ is a reserved method and, according to the docs, if a  
try to pickle an object that has a __getstate__ method, if you should  
pickle the output of __getstate__  as a representation of the object.  
It works in general but not with my example. I was able to pickle my  
special object using the copy_ref modules instead.

This came up because I am working on a new web2py feature (now  
experimental in trunk). I can pickle db objects (representing a  
connection and tables defined in the scope) that re-connects when I  
unpickle it. This allows me to create complex stateful objects that  
have a db connection and can be stored in a session and passed around  
(via xmlrpc for example). I am not sure yet if it is a good idea but  
I thought it was cool.

Massimo




On May 18, 2008, at 11:41 PM, Kumar McMillan wrote:

> On Sun, May 18, 2008 at 2:15 PM, Massimo Di Pierro
> <mdipierro at cs.depaul.edu> wrote:
>> The fact is that I can use copy_reg for the class S and does not  
>> fix the
>> problem. I can only fix the problem using copy_reg on the class A  
>> but only
>> this simple toy example. I am still running into problems into  
>> more complex
>> example although this should be straightforward. I guess the  
>> question is
>> why does __getstate__ behaves differently depending on the super  
>> classes but
>> the super.__getstate__ is not called?
>
> attributes prefixed with double underscores have different scoping
> rules in Python, they are essentially "private."  This *might* be the
> source of confusion around __getstate__ although admittedly I haven't
> spent time to completely understand the issue.
>
> http://diveintopython.org/object_oriented_framework/ 
> private_functions.html
>
>> Massimo
>>
>>
>> On May 18, 2008, at 2:07 PM, Atul Varma wrote:
>>
>> Let me rephrase the first sentence of my last post: I don't think  
>> the issue
>> is inheritance of just *any* class, but specifically inheritance  
>> of built-in
>> types. :)
>>
>> - Atul
>>
>> On Sun, May 18, 2008 at 12:06 PM, Atul Varma <varmaa at gmail.com>  
>> wrote:
>>>
>>> I could be wrong, but I don't think the issue is inheritance--I  
>>> think it's
>>> actually because you're subclassing a built-in type, which  
>>> requires doing
>>> some special stuff with pickle (namely, registering with copy_reg  
>>> as you've
>>> done in your last email).
>>>
>>> If you use pickle instead of cPickle, you get a more informative
>>> traceback; take a look at pickle.Pickler and notice how the  
>>> dispatch table,
>>> which appears to map types to serialization functions, maps the  
>>> dictionary
>>> type to Pickler.save_dict().  I think that has something to do  
>>> with it.
>>>
>>> Hope that helps...  I have to run so I can't look into this more  
>>> right
>>> now, but let me know if you'd like me to.
>>>
>>> - Atul
>>>
>>> On Sun, May 18, 2008 at 11:58 AM, Massimo Di Pierro
>>> <mdipierro at cs.depaul.edu> wrote:
>>>>
>>>> Odd... this works instead...
>>>>
>>>> from cPickle import *
>>>> import copy_reg
>>>>
>>>> class S(dict):
>>>>    def __getattr__(self,key): return self[key]
>>>>    def __setattr__(self, key, value): self[key]=value
>>>>
>>>> class A(S):
>>>>    def __init__(self): self.i=lambda u: u
>>>>    #def __getstate__(self): return {}
>>>>
>>>> def unserialize_A(d):
>>>>    return A()
>>>>
>>>> def serialize_A(o):
>>>>    return unserialize_A, ({},)
>>>>
>>>> copy_reg.pickle(A, serialize_A)
>>>>
>>>> a=A()
>>>> print a.i(3)
>>>> x=dumps(a)
>>>> b=loads(x)
>>>> print b.i(4)
>>>>
>>>> I guess the rule is use copy_reg and not __getstate__ if you have
>>>> inheritance.
>>>>
>>>>
>>>> On May 18, 2008, at 1:44 PM, Massimo Di Pierro wrote:
>>>>
>>>>> does anybody know why the following code does not work?
>>>>>
>>>>>     from cPickle import *
>>>>>
>>>>>     class S(dict):
>>>>>         def __setattr__(self, key, value): self[key]=value
>>>>>     class A(S):
>>>>>        def __init__(self): self.i=lambda u: u
>>>>>        def __getstate__(self): return {}
>>>>>
>>>>>     a=A()
>>>>>     x=dumps(a)
>>>>>
>>>>> I know that self.i is a lambda and thus not pickable but  
>>>>> __getstate__
>>>>> is called (I checked) and thus it should not matter. I guess I  
>>>>> do not
>>>>> undretansd how pickling under inheritance.
>>>>>
>>>>> Massimo
>>>>> _______________________________________________
>>>>> Chicago mailing list
>>>>> Chicago at python.org
>>>>> http://mail.python.org/mailman/listinfo/chicago
>>>>
>>>> _______________________________________________
>>>> Chicago mailing list
>>>> Chicago at python.org
>>>> http://mail.python.org/mailman/listinfo/chicago
>>>
>>
>> <ATT00001.txt>
>>
>> _______________________________________________
>> Chicago mailing list
>> Chicago at python.org
>> http://mail.python.org/mailman/listinfo/chicago
>>
>>
> _______________________________________________
> Chicago mailing list
> Chicago at python.org
> http://mail.python.org/mailman/listinfo/chicago



More information about the Chicago mailing list