[EMAIL PROTECTED] wrote:
What if I want to call other methods as well? Modifying your example a
bit, I'd like the reset() method call of Child to invoke both the
Mother and Father reset() methods, without referencing them by name,
i.e., Mother.reset(self).

-------------------
class Mother(object):
    def __init__(self, p_mother, **more):
        print "Mother", p_mother, more
        super(Mother, self).__init__(p_mother=p_mother, **more)
    def reset(self):
        print 'resetting Mother'

class Father(object):
    def __init__(self, p_father, **more):
        print "Father", p_father, more
        super(Father, self).__init__(p_father=p_father, **more)
    def reset(self):
        print 'resetting Father'

class Child(Mother, Father):
    def __init__(self, p_mother, p_father, **more):
        print "Child", p_mother, p_father, more
        super(Child, self).__init__(p_mother=p_mother,
                                    p_father=p_father, **more)
    def reset(self):
        print 'resetting Child'

        # I would like to invoke both Mother.reset()
        # and Father.reset() here, but it doesn't work.
        print 'trying "super"'
        super(Child, self).reset()

        # These next two do work, but require referencing
        # Mother and Father directly.
        print "calling directly"
        Mother.reset(self)
        Father.reset(self)

a = Child(1, 2)
a.reset()
-------------------

Thanks,
Phil

if you're going to be doing a bunch of these, you could define your own variant of the super type that calls all the methods in the mro with the given name. Below is a minor modification to the pure-python version of built-in super that illustrates this. There is no error-checking (e.g., if an attribute is callable in one class, and not callable in another you will hit problems) and it's not tested beyond what you see:

"""Hack on Super defined in http://python.org/2.2/descrintro.html
to call all super-class methods"""

class PolySuper(object):
    def __init__(self, type, obj=None):
        self.__type__ = type
        self.__obj__ = obj
    def __get__(self, obj, type=None):
        if self.__obj__ is None and obj is not None:
            return Super(self.__type__, obj)
        else:
            return self
    def __getattr__(self, attr):
        if isinstance(self.__obj__, self.__type__):
            starttype = self.__obj__.__class__
        else:
            starttype = self.__obj__
        mro = iter(starttype.__mro__)
        for cls in mro:
            if cls is self.__type__:
                break
        # Note: mro is an iterator, so the second loop
        # picks up where the first one left off!
        for cls in mro:
            if attr in cls.__dict__:
                x = cls.__dict__[attr]
                if hasattr(x, "__get__"):
                    x = x.__get__(self.__obj__)

                # return x
                # We want all the resolved methods, in order
                yield x
        #raise AttributeError, attr

    # Add this crude callable interface
    def __call__(self, attr, *args, **kw):
        methods = list(self.__getattr__(attr))
        return [method(*args, **kw) for method in methods]


Then, your classes get defined like so:

class Mother(object):
    def __init__(self, p_mother, **more):
        print "Mother", p_mother, more
    def reset(self):
        print 'resetting Mother'

class Father(object):
    def __init__(self, p_father, **more):
        print "Father", p_father, more
    def reset(self):
        print 'resetting Father'

class Child(Mother, Father):
def __init__(self, p_mother, p_father, **more):
print "Child", p_mother, p_father, more
PolySuper(Child, self)("__init__", p_mother = p_mother, p_father = p_father)
def reset(self):
print 'resetting Child'
PolySuper(Child, self)("reset")


 >>> c = Child("M1","F1")
 Child M1 F1 {}
 Mother M1 {'p_father': 'F1'}
 Father F1 {'p_mother': 'M1'}
 >>> c.reset()
 resetting Child
 resetting Mother
 resetting Father
 >>>

HTH
Michael

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to