def trace(func): name = func.__qualname__ def newfunc(*args): print("%s%s called" % (name, args)) result = func(*args) print("%s returns %s" % (name, repr(result))) return result return newfunc class base(object): @trace def __init__(self, *args): super(base, self).__init__() class i1(base): @trace def __init__(self, *args): super(i1, self).__init__("arg from i1") class i2(base): @trace def __init__(self, *args): super(i2, self).__init__("arg from i2") class top(i1, i2): @trace def __init__(self): super(top, self).__init__("arg from top") x = top()