Help with super()

Steven Bethard steven.bethard at gmail.com
Fri Jan 13 08:49:10 CET 2006


David Hirschfield wrote:
> Here's an example that's giving me trouble, I know it won't work, but it 
> illustrates what I want to do:
> 
> class A(object):
>    _v = [1,2,3]
>      def _getv(self):
>        if self.__class__ == A:
>            return self._v
>        return super(self.__class__,self).v + self._v
> 
>    v = property(_getv)
>  
> class B(A):
>    _v = [4,5,6]
>   b = B()
> print b.v
> 
> What I want is for b.v to give me back [1,2,3,4,5,6], but this example 
> gets into a recursive infinite loop, since super(B,self).v is still 
> B._getv(), not A._getv().

You don't actually need to use properties here if you don't want to -- 
the Class.v value can be calculated just once, at the time the class 
statement is executed:

 >>> class A(object):
...     class __metaclass__(type):
...         def __init__(cls, name, bases, classdict):
...             superclass = cls.mro()[1]
...             if superclass is object:
...                 v = []
...             else:
...                 v = list(superclass.v)
...             if 'v' in classdict:
...                 v.extend(cls.v)
...             cls.v = v
...     v = [1, 2, 3]
...
 >>> class B(A):
...     v = [4, 5, 6]
...
 >>> class C(B):
...     pass
...
 >>> class D(C):
...     v = [7, 8, 9]
...
 >>> A.v
[1, 2, 3]
 >>> B.v
[1, 2, 3, 4, 5, 6]
 >>> C.v
[1, 2, 3, 4, 5, 6]
 >>> D.v
[1, 2, 3, 4, 5, 6, 7, 8, 9]
 >>> B.v is C.v
False

Note that A.__metaclass__.__init__ is called when the A, B, C and D 
class statements are executed.  This code simply looks at the superclass 
of class being created, and creates the appropriate v list.

Note that this approach means that you only create the lists once, 
instead of creating them each time your getv() method is called. 
However, if the list in a superclass changes, the subclass lists will 
not be automatically updated.

HTH,

STeVe



More information about the Python-list mailing list