Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize an instance using pickle()?

Tags:

python

I want to define a class that is able to populate itself reading from the serialized data of another instance. Here's the simplified code:

class MyClass(list):

    def __init__(self,**kwargs):
        if kwargs.has_key('fdata'):
            f = open(kwargs['fdata'],'r')
            self = pickle.load(f)
            print len(self)    #prints 320          
            f.close()              

    ...

a = MyClass(fdata='data.dat')
print len(a)    #prints 0

This is the output I obtain:

320
0

The problem I have is that the instance returned is always empty, even though I am able to read all the elements inside __init__() What can be causing this?

like image 700
Juan M Rivas Avatar asked Jun 28 '12 12:06

Juan M Rivas


2 Answers

Assigning to self inside a method simply rebinds the local name self to a different object. Assignments to bare names in Python can never modify any object – they just rebind names.

Why don't you use the straight-forward

with open("data.dat") as f:
    a = pickle.load(f)

instead of constructing a new class? If you don't like this, wrap this in a function, but it's not that useful to put this code into __init__().

There are other ways to achieve the same effect. Probably the best way to achieve exactly what you are trying is to overwrite __new__() instead of __init__()__new__() is called before the new instance is constructed, so you can simply return the unpickled instance instead of having to modify an already constructed one.

like image 130
Sven Marnach Avatar answered Oct 06 '22 19:10

Sven Marnach


self is a regular local variable in Python. You can't use self = other to make an object "become" something else, you'll just reassign the local. You'll have to restore the attributes one-by-one, or use something like:

self.__dict__ = pickle.load(f).__dict__

(I haven't tested that last line, it might well make your kittens explode.)

like image 41
millimoose Avatar answered Oct 06 '22 19:10

millimoose