[Zope] Bound methods, acquisition, __init__, Unpickleable object

Bo Granlund granbo@uiah.fi
Mon, 9 Jul 2001 19:28:26 +0300


Thank you for your quick reply. I really was starting to get
desperate with this thing.

On Mon, Jul 09, 2001 at 08:40:34AM -0600 cduncan@kaivo.com wrote:
> Now to get around the problem of storing functions, I would suggest
> storing the name of the function (a string) in the list instead of the
> function itself. The use getattr to retreive it when it is called. Here
> is your code revised to do this:
> 
> class Root(Acquisition.Implicit, Persistent):
>         def __init__(self):
>                 self.container = []
>         def register_func(self, func_name):
>                 self.container.append(func_name)
> 		self._p_changed = 1
> 	def call_func(self, func_index):
>                 getattr(self.aq_base, self.container[func_index])()

I think this code is doomed to raise an AttributeError exception,
unless it would happen that Root has a func_name method. The idea
was to call the func_name method of Spam class, not Root. I guess
the following example is the only way to do it (I hope I'm
mistaking here, really):

class Root(Persistent):
	__doc__ = 'This is the products root object.'
	def __init__(self):
		self.callbacks = []
	def register_func(self, func_name, obj_path):
		self.callbacks.append((func_name, obj_path))
	def call_functions(self):
		for (func, objn) in self.callbacks:
			to = self.aq_base
			for o in objn.split('.'):
				to = getattr(to, o)
			getattr(to, func)()

That way just just find out the path to the object holding the
method, and store a "pointer" to it:

	self.register_func(self.do_it, 'foo.bar.ni.spam')
	# Where root_obj.foo.bar.ni.spam is the Spam-object.

Hrm. A simple method reference would be so much nicer, but you
can't win everytime.


best regards,
Bo Granlund