Extension class and __init__
I had the bright idea of defining a mixin class whose methods I thought I could use in my regular Zope product classes: class AMixin: def __init__(self): blah, blah blah class B(AMixin, Persistent, Folder, ....): def __init__(self): # do some of my own stuff AMixin.__init__(self) This fails with the warning (as I recall) that the unbound method AMixin.__init__ needs to be called with an instance as its first argument. (I've stripped the example down to give what I think are the essentials). self in the context of B is an Extension class, and I'm guessing this is making AMixin unhappy because it's not. I assume I'll have the same problem with other methods that I attempt to access using AMixin.foo(self). Can anyone confirm this diagnosis? And what's the best solution? I have redefined things class AMixin: def _mixin_init(self): #stuff class B(AMixin, .....): def __init__(self): #my own stuff self._mixin_init(self) and this seems to work, but I wonder if there's a way to get the classes to play together better (maybe "class AMixin(ExtensionClass):"? though since ExtensionClass is a type I guess that's not exactly it). This was after already discovering that isinstance doesn't work with ExtensionClass (which I see confirmed on the list, along with the fact that ExtensionClass generally has a lot of rough spots and may be on the way out). This is with Zope 2.5.1.
Ross, Please see the bit about "inheritedAttribute" in the document inside Zope's source tree named lib/Components/ExtensionClass/doc/ExtensionClass.html. HTH, - C ----- Original Message ----- From: "Ross Boylan" <RossBoylan@stanfordalumni.org> To: <zope-dev@zope.org> Cc: "Ross Boylan" <RossBoylan@stanfordalumni.org> Sent: Monday, July 22, 2002 3:30 AM Subject: [Zope-dev] Extension class and __init__
I had the bright idea of defining a mixin class whose methods I thought I could use in my regular Zope product classes:
class AMixin: def __init__(self): blah, blah blah
class B(AMixin, Persistent, Folder, ....): def __init__(self): # do some of my own stuff AMixin.__init__(self)
This fails with the warning (as I recall) that the unbound method AMixin.__init__ needs to be called with an instance as its first argument. (I've stripped the example down to give what I think are the essentials).
self in the context of B is an Extension class, and I'm guessing this is making AMixin unhappy because it's not. I assume I'll have the same problem with other methods that I attempt to access using AMixin.foo(self).
Can anyone confirm this diagnosis? And what's the best solution?
I have redefined things class AMixin: def _mixin_init(self): #stuff
class B(AMixin, .....): def __init__(self): #my own stuff self._mixin_init(self)
and this seems to work, but I wonder if there's a way to get the classes to play together better (maybe "class AMixin(ExtensionClass):"? though since ExtensionClass is a type I guess that's not exactly it).
This was after already discovering that isinstance doesn't work with ExtensionClass (which I see confirmed on the list, along with the fact that ExtensionClass generally has a lot of rough spots and may be on the way out). This is with Zope 2.5.1.
_______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
On Mon, Jul 22, 2002 at 08:52:27AM -0400, Chris McDonough wrote:
Ross,
Please see the bit about "inheritedAttribute" in the document inside Zope's source tree named lib/Components/ExtensionClass/doc/ExtensionClass.html.
HTH,
- C
The trick given there doesn't seem to work in complicated cases. The example there is basically class Spam: def __init__(self): ... class ECSpam(Base, Spam): #Base is an ExtensionClass def __init__(self): ECSpam.inheritedAttribute('__init__')(self) What if you have more than one base class with the method defined? The implication of th example is that the non-extension class base class is used (though even that is not clear; would this work if Base had __init__?), but what if there are several non-extension base classes? The syntax doesn't provide a way of indicating which class you want the method from, and so it seems incomplete.
Here is another trick: <http://lists.zope.org/pipermail/zope/2002-June/116094.html> HTH, Stefan On Fri, 26 Jul 2002, Ross Boylan wrote:
The syntax doesn't provide a way of indicating which class you want the method from, and so it seems incomplete.
From: "Ross Boylan" <RossBoylan@stanfordalumni.org>
What if you have more than one base class with the method defined? The implication of th example is that the non-extension class base class is used (though even that is not clear; would this work if Base had __init__?), but what if there are several non-extension base classes?
In my experience you simply shouldn't have several non-extension base classes.
Erm... that trashes the concept of mixin's, doesn't it? I mean, if I have a mixin, that happens to need some initialization (Probably not as uncommon as people seem to think), then what do I have to do, have a single non-EC class that groups all the mixin's, then create a subclass combining my ECbase and my MultiMixinCombinedBase ??? Seems a little convoluted to me, and generally speaking, convoluted is bad. Adrian... -- Adrian Hungate EMail: adrian@haqa.co.uk Web: http://www.haqa.co.uk ----- Original Message ----- From: "Lennart Regebro" <lennart@torped.se> To: "Ross Boylan" <RossBoylan@stanfordalumni.org>; <zope-dev@zope.org> Sent: Friday, July 26, 2002 11:29 PM Subject: Re: [Zope-dev] Extension class and __init__
From: "Ross Boylan" <RossBoylan@stanfordalumni.org>
What if you have more than one base class with the method defined? The implication of th example is that the non-extension class base class is used (though even that is not clear; would this work if Base had __init__?), but what if there are several non-extension base classes?
In my experience you simply shouldn't have several non-extension base classes.
_______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
From: "Adrian Hungate" <adrian@haqa.co.uk>
Erm... that trashes the concept of mixin's, doesn't it?
No, why would it? Just make your mixins inherit Extentionclass.base! If you have third-party mixins that aren't made for Zope from the beginning and need initailization, then you probably have to Zopify them first. I don't see how this is convoluted. It's not obvious to non-Zope gurus, but that is what comments are for. :-)
Ross Boylan wrote:
class ECSpam(Base, Spam): #Base is an ExtensionClass def __init__(self): ECSpam.inheritedAttribute('__init__')(self)
What if you have more than one base class with the method defined?
The normal Python inheritted attribute lookup rules: depth first, left to right through the list of base classes.
The implication of th example is that the non-extension class base class is used
If Spam defines __init__ and Base doesn't, that would be the case...
(though even that is not clear; would this work if Base had __init__?),
No, in that case Base's __init__ would be used, see python inheritence rules.
but what if there are several non-extension base classes?
See python inheritence rules...
The syntax doesn't provide a way of indicating which class you want the method from, and so it seems incomplete.
Well, if you wanted it to come from Base specifically, you could do: Base.inheritedAttribute('__init__')(self) not sure about the non-EC bases, perhaps Jim could clarify this? cheers, Chris
_______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Ross Boylan writes:
The example there is basically class Spam: def __init__(self): ...
class ECSpam(Base, Spam): #Base is an ExtensionClass def __init__(self): ECSpam.inheritedAttribute('__init__')(self) I started to use the following idiom:
class ECSpam(...,Spam): ... _Spam__init= Spam.__init__ def __init__(self): self._Spam__init() i.e., rename the overloaded method in you derived class and call it in the normal way with its new name. Dieter
participants (7)
-
Adrian Hungate -
Chris McDonough -
Chris Withers -
Dieter Maurer -
Lennart Regebro -
Ross Boylan -
Stefan H. Holek