copy_reg problem - UPDATE! PLEASE READ!

Rainer Deyke root at rainerdeyke.com
Sun Oct 8 13:45:07 EDT 2000


"Martin von Loewis" <loewis at informatik.hu-berlin.de> wrote in message
news:p6q8zrzz4hr.fsf at informatik.hu-berlin.de...
> "Rainer Deyke" <root at rainerdeyke.com> writes:
>
> > Appearantly copy_reg.pickle only works for types, not classes (despite
the
> > documentation saying otherwise).
>
> I'd say the documentation is wrong, not the code.
>
> > I really need this to work for class instances for two reasons:
> >
> >   1. It allows me to later replace a class with a C extension type.
>
> Can you please elaborate? What is it that you want to do, and why is
> that a good thing?

class A:
  ...

def create_A(data):
  return A(data)

def pickle_A(a):
  return create_A, (a.get_data(),)

copy_reg.pickle(A, pickle_A, create_A)

I can later move the implementation of A into a C extension type and still
be able to load old pickles containing A by replacing the create_A function
(which is pickled by name).  This is important, because my current project
may require better performance than Python can provide.

> >   2. It allows me to "merge" objects from different pickles.
>
> Again, I don't understand. In what way do you want to merge objects
> from different pickles, and why is there no other way to achieve the
> same effect?

I have a variety of interconnected persistant objects which can't all be
loaded into memory at the same time.  Therefore I want pickled objects that
when loaded connect to the objects that are already in memory.  I wrote a
class to facilitate this (shown in simplified form):

class ResourceDescriptor:
  def __init__(self, name):
    self.name = name
    self.object = None
  def get(self):
    if self.object is None:
      self.object = load_resource(self.name)
      # load_resource ultimately loads a pickle from a database
    return self.object

resource_descriptors = {}

def get_resource_descriptor(name):
  if not resource_descriptors.has_key(name):
    resource_descriptor[name] = ResourceDescriptor(name)
  return resource_descriptors[name]

# There is also a function to delete resource descriptors that are
# no longer needed.

Resource objects reference other resource objects indirectly through
references to ResourceDescriptor instances.  However, the system relies on
ResourceDescriptor instances being pickled by name, not state: otherwise I
end up with duplicate objects loaded, which is unacceptable. (The full
implementation of ResourceDescriptor allow mutable resources, which are
written back to the database before being unloaded.)  I could approach this
problem by transforming ResourceDescriptor instances to strings and vice
versa in the resourc objects' __getstate__ and __setstate__ methods, but
this approach is messy.

A more simple example would a singleton:

class S:
  pass

the_S = S()

def get_the_S():
  return the_S

def pickle_S(s):
  return get_the_S, ()

copy_reg.pickle(S, pickle_the_S, get_the_S)


--
Rainer Deyke (root at rainerdeyke.com)
Shareware computer games           -           http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor





More information about the Python-list mailing list