Last active
May 20, 2022 03:08
-
-
Save pmelchior/e3e0049974365319a8b1478deb0112e9 to your computer and use it in GitHub Desktop.
Source code for python class instance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import inspect | |
from IPython.display import Code | |
def get_source_code(obj, display=False): | |
if inspect.isclass(obj): | |
this_class = obj | |
else: | |
# get class from instance | |
this_class = type(obj) | |
try: | |
# try to get file: if so, source code is available directly | |
inspect.getfile(this_class) | |
source = inspect.getsource(this_class) | |
except TypeError: | |
# manually get source for all methods that are altered in this_class | |
# get parent class (if none, returns 'object' as the default base class) | |
parents = type(obs).__bases__ | |
assert len(parents) == 1, "search only implemented for single base class" | |
parent_class = parents[0] | |
source = f"class {this_class.__name__}({parent_class.__module__}.{parent_class.__name__}):\n" | |
# find the members that got changed in this_class | |
# from https://stackoverflow.com/a/48281090 | |
a = dict(inspect.getmembers(parent_class)) | |
b = dict(inspect.getmembers(this_class)) | |
for k, v in b.items(): | |
if k != '__init__' and k.startswith('__'): | |
continue | |
if k not in a or v != a[k]: | |
# get class method by name | |
# from https://stackoverflow.com/a/30485548 | |
if isinstance(v, property): | |
source += "\n" + inspect.getsource(v.fget) | |
else: | |
source += "\n" + inspect.getsource(v) | |
if not display: | |
return source | |
else: | |
# from https://stackoverflow.com/a/65680105 | |
return Code(source, language='python') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment