Welcome, guest | Sign In | My Account | Store | Cart

The code based on http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195 but interface is PEP 367 like so you can write just super.base_method() inside a method. See doctests for examples.

Python, 61 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import sys


class Super(object):
    """
    >>> class A(object):
    ...     def a(self):
    ...         print "A.a()"

    >>> class B(A):
    ...     def a(self):
    ...         print "B.a()"
    ...         super.a()

    >>> b = B()
    >>> b.a()
    B.a()
    A.a()

    >>> class C(B):
    ...     def a(self):
    ...         print "C.a()"
    ...         super.a()

    >>> c = C()
    >>> c.a()
    C.a()
    B.a()
    A.a()
    """

    def __getattribute__(self, name):
        frame = sys._getframe(1)
        code = frame.f_code
        if code.co_argcount < 1:
            raise TypeError("super used in wrong context")
        caller_obj = frame.f_locals[code.co_varnames[0]]

        caller_class = None
        for c in type(caller_obj).__mro__:
            try:
                func_code = getattr(c, name).func_code
            except AttributeError:
                func_code = None

            if func_code is code:
                caller_class = c
            elif caller_class is not None:
                break
        else:
            raise TypeError("super used in wrong context")

        super_obj = __builtins__.super(caller_class, caller_obj)
        return getattr(super_obj, name)

super = Super()


if __name__ == "__main__":
    import doctest
    doctest.testmod()