[ZODB-Dev] Pickling methods and workarounds

Christian Robottom Reis kiko at async.com.br
Fri Feb 27 17:35:50 EST 2004


So today I ended up having to modify the behaviour in one of my
classes, and my initial plan was to customize this behaviour using a
method stored as an instance attribute. So I had something like:

    class Foo(Persistent):
        def __init__(self):
            self.bar = self._real_bar_A

        def enable_plan_b(self):
            self.bar = self._real_bar_B

        def _real_bar_A(self, a):
            print a + 1
        
        def _real_bar_B(self, a):
            print a - 1

        def foo(self):
            self.bar(0)

My plan is to call foo() and it have the right method be called, based
on what the bar attribute is set to. However, this bombs out on me with
the too familiar

      File "/mondo/local//lib/python2.3/site-packages/ZODB/Transaction.py", line 233, in commit
        ncommitted += self._commit_objects(objects)
      File "/mondo/local//lib/python2.3/site-packages/ZODB/Transaction.py", line 348, in _commit_objects
        jar.commit(o, self)
      File "/mondo/local//lib/python2.3/site-packages/ZODB/Connection.py", line 423, in commit
        dump(state)
      File "/mondo/local/lib/python2.3/copy_reg.py", line 69, in _reduce_ex raise TypeError, "can't pickle %s objects" % base.__name__
    TypeError: can't pickle function objects

exception. AFAIK this holds true, still, so I'm looking for experience
and/or workarounds that "somebody" might have produced while working in
situations like these. The ones I see at the moment are:

    - Storing the method name as an instance attribute, and doing:

        def __init__(self):
            self.plan_method = "_real_bar_A"

        def enable_plan_b(self):
            self.plan_method = "_real_bar_B"

        # ...

        def foo(self):
            getattr(self, self.plan_method)(0)

      which is quite ugly.

    - Using an if clause in foo(), which adds some minor overhead, but
      uglifies the code in every callsite that wants to call bar().

Does anybody have advice for this situation?

Take care,
--
Christian Robottom Reis | http://async.com.br/~kiko/ | [+55 16] 261 2331



More information about the ZODB-Dev mailing list