[Zope] publish() hook
Paul Winkler
pw_lists@slinkp.com
Tue, 23 Apr 2002 14:57:20 -0700
On Tue, Apr 23, 2002 at 09:58:30PM +0200, Dieter Maurer wrote:
> The "user" probably does
>
> from ZPublisher.Publish import publish
>
> Then, later changes to "ZPublisher.Publish" do not affect the imported
> "publish".
python cookbook to the rescue!
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/92823
Ignore the specifics, just notice the principle.
Here's a simple example:
$ python
Python 1.5.2 (#1, Aug 25 2000, 09:33:37) [GCC 2.96 20000731 (experimental)] on linux-i386
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> class Foo:
... def bar(self, arg):
... print arg
...
>>> def newbar(self, arg, oldbar=Foo.bar): # have to pass in the old method
... print "Now in newbar, and calling the old one"
... oldbar(self, arg)
...
>>> x = Foo()
>>> x.bar(1)
1
>>> Foo.bar=newbar # substitute the new method
>>> x.bar(1)
Now in newbar, and calling the old one
1
So you can redefine a method and see the effect in all existing
(and future) instances. AFAIKT this should work regardless of how the
class gets imported anywhere else.
When I first heard this idea, I mistakenly thought it was just the Decorator
design pattern, but clearly it's much more wide-reaching...
Decorator, for any readers who don't know, shows how to change the behavior
of a *single instance* of a class and leave all other instances alone.
Probably not what you want in this case, but a very powerful tool anyway,
and very easy in python.
Here's an example, continuing from the above python session:
>>> class Decorator:
... def __init__(self, original):
... self.original=original
... def bar(self, arg):
... print "This is the decorated version..."
... self.original.bar(arg)
... print "we now return to your regularly scheduled programming."
...
>>>
>>> y = Foo()
>>> x = Decorator(x)
>>> x.bar("blah")
This is the decorated version...
Now in newbar, and calling the old one
blah
we now return to your regularly scheduled programming.
>>> y.bar("bleah")
Now in newbar, and calling the old one
bleah
>>> x = x.original
>>> x.bar("wheeee")
Now in newbar, and calling the old one
wheeee
Now back to my C++ homework. It's not nearly this much fun. :(
--PW