Override a method of an instance in the ZODB?
Hello zope gurus, I'm wondering if it is possible to override a method on a single instance of an object in the ZODB. My suspicion is no, but it doesn't hurt to ask. Specifically, I've tried: def userFolderDelUsers(self, names): pass from types import MethodType setattr(acl_users, 'userFolderDelUsers', MethodType(userFolderDelUsers, acl_users, acl_users.__class__)) Which works fine until the transaction gets committed, at which point it fails with "TypeError: can't pickle function objects". Which seems pretty much like a lost cause. Can you only do this at the class level? Is there an unrelated way to accomplish the same goal (overriding a method, without monkeypatching or subclassing)? Thanks for any enlightenment, Alec Mitchell
From: "Alec Mitchell" <apm13@columbia.edu>
Hello zope gurus,
I'm wondering if it is possible to override a method on a single instance of an object in the ZODB. My suspicion is no, but it doesn't hurt to ask. Specifically, I've tried:
def userFolderDelUsers(self, names): pass
from types import MethodType setattr(acl_users, 'userFolderDelUsers', MethodType(userFolderDelUsers, acl_users, acl_users.__class__))
Which works fine until the transaction gets committed, at which point it fails with "TypeError: can't pickle function objects". Which seems pretty much like a lost cause. Can you only do this at the class level? Is there an unrelated way to accomplish the same goal (overriding a method, without monkeypatching or subclassing)?
How about simple acquisition? eg Folder A | | --Method AAA | --Folder B | |-- Method AAA Method AAA in Folder B will be found by acquisition before Method AAA in Folder A (assuming you set up the path that way). Jonathan
On Thursday 27 May 2004 01:19 pm, Small Business Services wrote:
How about simple acquisition?
eg
Folder A
| --Method AAA | --Folder B | |-- Method AAA
Method AAA in Folder B will be found by acquisition before Method AAA in Folder A (assuming you set up the path that way).
I'm a big fan of acquisition myself, but in this case the method is generally called in the context of the object itself e.g.: context.acl_users.userFolderDelUsers(stuff) Which won't acquire anything but the method. The reason I want to avoid a subclass or monkey patch is that I want to override what this method does for this one instance of an already populated acl_users without changing it in any other way. Thanks, Alec Mitchell
Alec Mitchell wrote at 2004-5-27 13:11 -0700:
I'm wondering if it is possible to override a method on a single instance of an object in the ZODB. My suspicion is no, but it doesn't hurt to ask.
You can but it is a bit tricky because Python performs method wrapping only for class attributes. Thus, you need to do your own wrapping. Something like this: from Acquisition import Explicit class _MethodWrapper(Explicit): def __init__(self, f): self.__f = f def __call__(self, *args, **kw): return self.__f(self.aq_parent, *args, **kw) instance.f = _MethodWrapper(your_funcion) Note, that your "your_function" must be pickleable and unpickleable. This means, it must be defined in the module (global) namespace. -- Dieter
On Friday 28 May 2004 11:52 am, Dieter Maurer wrote:
Alec Mitchell wrote at 2004-5-27 13:11 -0700:
I'm wondering if it is possible to override a method on a single instance of an object in the ZODB. My suspicion is no, but it doesn't hurt to ask.
You can but it is a bit tricky because Python performs method wrapping only for class attributes.
Thus, you need to do your own wrapping. Something like this:
from Acquisition import Explicit class _MethodWrapper(Explicit): def __init__(self, f): self.__f = f def __call__(self, *args, **kw): return self.__f(self.aq_parent, *args, **kw)
instance.f = _MethodWrapper(your_funcion)
Note, that your "your_function" must be pickleable and unpickleable. This means, it must be defined in the module (global) namespace.
Great! That's exactly what I was looking for. Thanks, Alec Mitchell
Alec Mitchell wrote:
Note, that your "your_function" must be pickleable and unpickleable. This means, it must be defined in the module (global) namespace.
Great! That's exactly what I was looking for.
You should probably have a nose at SimpleUserFolder too :-) Chris -- Simplistix - Content Management, Zope & Python Consulting - http://www.simplistix.co.uk
participants (4)
-
Alec Mitchell -
Chris Withers -
Dieter Maurer -
Small Business Services