super question

Michele Simionato mis6 at pitt.edu
Wed Apr 9 20:52:47 CEST 2003


Lee Harr <missive at frontiernet.net> wrote in message news:<WRBka.134$jS3.16 at news02.roc.ny.frontiernet.net>...
> I guess I do not get it.
> 
> 
> >>> class A(object):
> ...   def f(self):
> ...     print 'Af'
> ... 
> >>> class B(object):
> ...   def f(self):
> ...     print 'Bf'
> ... 
> >>> class C(A, B):
> ...   def f(self):
> ...     super(C, self).f()
> ... 
> >>> c=C()
> >>> c.f()
> Af
> 
> 
> Should this be showing
> Af
> Bf
> ?
> 
> How would I even get that output?  I know I can do:
> 
> class C(A, B):
>   def f(self):
>     A.f(self)
>     B.f(self)
> 
> 
> but I can't seem to get that out of super()

If metaclasses don't scare you, here there is the solution:

class MakeCooperative(type):
    "A custom metaclass making cooperative a given list of methods"
    def __init__(cls,name,bases,dic):
        "Makes cooperative the methods in the method list"
        for meth in cls.methods:   
            setattr(cls,meth,cls.coop_method(meth,dic.get(meth)))
    def coop_method(cls,name,method):
        "Given a regular method, returns a cooperative method"
        def _(self,*args,**kw):
            try: supermethod=getattr(super(cls,self),name)
            except: pass # do nothing
            else: supermethod(*args,**kw) # calls the supermethod
            if method: method(self,*args,**kw) # calls the method
        return _
    def method(meta,methods=''):
        """Generates the list of cooperative methods from an input string
        and returns the metaclass"""
        meta.methods=methods.split()
        return meta
    method=classmethod(method) # this is a metaclass-level classmethod
    
class A(object):
    __metaclass__ = MakeCooperative.method('f')
    def f(self):
        print 'Af'

class B(object):
    def f(self):
       print 'Bf'
       
class C(A, B):
    def f(self):
        print 'Cf'

c=C()
c.f()

# Output:
# Bf
# Af
# Cf




More information about the Python-list mailing list