[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