2

I want to be able to print out a "flattened" version of a class - viewing the source code of Class B which inherits methods from Class A but as if it were written as a single class without inheritance.

The Python inspect module provides the getsourcelines(B) method, which works great for combining both A and B code. But, if my method in B includes an overridden class that calls super(), this approach only shows that the super() line exists, not what the source code in class A contains. Here's an example:

import inspect

class A(object):
    def a_method(self):
        self.a = 4
        return self.a
    def overridden(self):
        print('This is A')

class B(A):
    def c_method(self):
        pass
    def overridden(self):
        print('This is C')
        print('Calling super of C:')
        super().overridden()


output = ''
for name, member in inspect.getmembers(B):
    #skip builtins for example
    if name.startswith('__') == True:
        pass
    else:
        lines, location = inspect.getsourcelines(member)
        for line in lines:
            output += line

print(output)

This prints to the command line:

def a_method(self):
    self.a = 4
    return self.a
def c_method(self):
    pass
def overridden(self):
    print('This is C')
    print('Calling super of C:')
    super().overridden()

Is there a way that I can replace the line super().overridden() in the output with the contents of A.overridden()?

Neal
  • 3,102
  • 1
  • 14
  • 16
  • but why should it? One of the reasons for using `super()` is in order to not hardcode any class names and essentially locate the method at run time based on the MRO. I'm very doubtful you'd be able to find a robust solution to this. – Dimitris Fasarakis Hilliard Mar 29 '17 at 16:42
  • The reason for me is so that when I'm working on a new project (new to me) that has nested structures, I can quickly get up to speed on what code each method of the class executes. I want the live code to use `super()` as you describe, but I want a tool that lets me view what would be run based on the MRO in a format that doesn't require quite so much hunting. I can use the `inspect.getmro(B)` to get the order but the only way I know of currently is to manually inspect the line and see if it has `super().methodname()` in it, was hoping there was something that does that already. – Neal Mar 29 '17 at 17:37
  • Updated my title per Jim's question - I know that getsourcelines() doesn't return super(), but I want something that does. – Neal Mar 29 '17 at 17:42
  • 1
    This isn't going to work. For one thing, the subclass and superclass methods have separate local variables, which your code is going to display as if they're the same. For another, argument passing isn't going to make much sense. – user2357112 Mar 29 '17 at 19:09
  • @user2357112 Good point on local variables and argument passing. For me it's not a requirement to actually execute the resulting code - I will be executing the real version. If I wanted to make it truly executable I could probably come up with something that added new methods called something like `classname_methodname()` and swap the super() line for a call to `classname_methodname()`. For reference, I am trying to add this to this project, which has a good GIF image showing the resulting output in an HTML page: https://github.com/tatterdemalion/classdigger – Neal Mar 29 '17 at 19:20

0 Answers0