N
Nicolas Fleury
Is it possible to use the pickle module to update an object instead of
creating a new instance?
Thx
Nicolas
creating a new instance?
Thx
Nicolas
Nicolas said:Is it possible to use the pickle module to update an object instead of
creating a new instance?
Matteo said:I don't get what you want to do. Can you explain yourself better? What
do you mean by "updating" an object?
Nicolas said:Use the same reference instead of creating a new instance. Basically
making pickle call __init__ of an existing object. The best solution I
see for now is to copy the __dict__ of the new object to the existing
one. I want to update the content of an object with a dumped object of
the same type so that all reference to existing object are still valid.
Nicolas said:I want to update the content of an object with a dumped object of the
same type so that all reference to existing object are still valid.
Leif said:Add interfaces to your object's class for mutability rather than using a
low-level hack. Something like this (untested):
Nicolas said:Thx for your answer, but according to what I read about __slots__, this
feature has never been intended to be used that way either, so it's also
a kinda low-level hack, no? It is still an interesting solution.
Using __slots__ is just an optimization, it isn't directly related to
the example. This would also work:
class cls:
def __init__(self, foo=None):
self.foo = foo
def set_foo(self, foo):
self.foo = foo
foo = cls(42)
bar = foo
print bar.foo # 42
foo.set_foo(43)
print bar.foo # 43
Matteo said:I guess you have to find a way to encapsulate information, and maybe a
proxy could be OK for you (I can't find the recipe in the Python
Cookbook right now, since it appears to be down).
Stefan said:Hi there (,hi Nicolas !),
...I'm still lost: how is this interface-enriched declaration helping
in the task to retrieve ('internalize') an object's state from a pickle ?
Looking again into the docs for the pickle protocol, I wonder whether there
isn't any place in the __init__/__reduce__/__setstate__ magic to throw in
some meta-programming (i.e. an intelligent metaclass doing the job), or
providing
a clever __new__ operator that doesn't return a new object but an
existing one,
etc., etc.
Nicolas said:Hi Stefan,
You're right, the example shows how to copy and it creates a new
reference, so it doesn't help in the problem (I realized it when going
back home yesterday).
Nicolas said:I just added a feature request on sf to have an updating load function
in pickle. My preferred solution for now might still be the copy of
__dict__ (I could copy slots also), it's simple and not intrusive (using
proxies is, even if less a hack). However, the cleanest solution would
be to implement your solution, but I have no idea how to do it for now.
Matteo said:Well, it's not possible: variables are just names attached to objects,
and while you can assign a name to an object, you *can't* change the
object's type, or replace an object with another one.
And I think that copying __dict__ is a hack: it wouldn't work, for
instance, with builtin types, when __slots__ are used, or when you are
using properties.
A transparent proxy is a clean way to do it: through delegation, it
would work with any kind of object, changes in code are localized in the
load/save part, and the rest of the application wouldn't even notice.
Nicolas said:I think it is acceptable that this pickle.update function would only
accept reference of same type and raise an exception otherwise. The
point of pickle.update would be to not "replace an object with another
one" but to call __init__ on an existing object.
Matteo said:I still don't understand how exactly you would want it to work. If you
want to call __init__ on an existing object, why don't you just do it
explicitly? Could you post some equivalent code to what you would want
pickle.update to do?
Matteo said:I still don't understand how exactly you would want it to work. If you
want to call __init__ on an existing object, why don't you just do it
explicitly? Could you post some equivalent code to what you would want
pickle.update to do?
Stefan said:Think of a 'persistence storage service' that could look like this:
store = Persistence.Store('foobar')
object.store(store) # persists the object's state into the store
...
object.restore(store) # restore the object's state from the store
Of course, here 'object' has to implement some 'Storable' interface,
so it's quite intrusive (and thus not really what Nicolas is looking for).
It's just to illustrate the purpose, anyways.
With python's metaprogramming and introspection capabilities the same
could be achieved without the need for a specific base class. Well,
may be a specific __metaclass__, I don't know.
It really seems to me that pickle already contains the functionality
that would be required (after all pickle *can* deal with object graphs,
so it has to track object ids internally), it just needs to be exposed
to the user. I believe that's precisely what Nicolas' enhancement request
is all about.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.