Re: Intercepting __getattr__ in a Python 2.3 old-style mixin class?
Leonardo Rochael Almeida <[email protected]> Mon, 7 Nov 2016 12:54:59 -0200
| Newsgroups | gmane.comp.web.zope.devel |
|---|---|
| Message-ID | <CAMxX_oMCdnXVVSJu32ReGJo8J1=WoZBvzMWxvCuePrd8MjYkfQ@mail.gmail.com> |
Hi Andreas, As Hanno said, you'll still be in old-style-classes-land even in Python 2.7 unless you inherit from `object` directly. You said: My idea is to inject a common mixin class like > class Foo(Bar, Mixin): > ... > class Mixin: > def __getattr__(self, k) > print repr(self), k > return Foo.__getattr__(self, k) Your recursion error is caused by calling `Foo.__getattr__(self, k)` from `Mixin`, but `Foo` inherits from `Mixin`. Calling a method of a subclass from the same-named method in the superclass is a recurssion. Instead `Mixin` needs to call `Bar.__getattr__` since `Bar` is the superclass to `Foo`. Alternatively, if you don't want to name any specific superclass inside the mixin method, (and since you can't use `super()` since you're using old-style classes), I suggest a different approach. Instead of a mixin class, use a method factory, like this: def my__getattr__factory(SuperClass): > def __getattr__(self, k): > print repr(self), k > return SuperClass.__getattr__(self, k) Which you can then use as: class Foo(Bar): # <- No mixin > __getattr__ = my_getattr__generator(Bar) # <- Bar, not Foo Regards, Leo On 7 November 2016 at 12:29, Hanno Schlichting <[email protected]> wrote: > On Mon, Nov 7, 2016, at 14:01, Andreas Jung wrote: > > Python 2.7 is different because all classes are automatically new-style > > classes. > > In Python 2.7 you would have to overwrite __getattribute__() but I am on > > Python 2.3 here. > > No :) > > In Python 3 all classes are new-style classes. In Python 2 (including > 2.7) you have to be explicit and either inherit from object (new-style) > or not (old-style). > > In Python 2.7 you get: > > >>> class A: pass > >>> class B(object): pass > >>> type(A) > <type 'classobj'> > >>> type(B) > <type 'type'> > > In Python 3 both are of type 'type'. > > And only new-style classes use '__getattribute__'. '__getattr__' is the > right approach for old-style classes in any Python 2 version, even in > Python 2.7. > > Hanno > _______________________________________________ > Zope-Dev maillist - [email protected] > https://mail.zope.org/mailman/listinfo/zope-dev > ** No cross posts or HTML encoding! ** > (Related lists - > https://mail.zope.org/mailman/listinfo/zope-announce > https://mail.zope.org/mailman/listinfo/zope ) > _______________________________________________ Zope-Dev maillist - [email protected] https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )