Search code examples
pythoninheritanceintrospection

Retrieving arguments from a class with multiple inheritance


Is it possible to retrieve all arguments from an object, that has multiple parent classes, using inspect.getargspec()or any other option?

Example:

import inspect

class One:
    def __init__(self,a):
        self.a = a

class Two:
    def __init__(self,b):
        self.b = b

class Three(One, Two):
    pass

print(inspect.getargspec(Three.__init__))

Instead: ArgSpec(args=['self', 'a'], varargs=None, keywords=None, defaults=None) as an output, I am looking for the way to have: ['self', 'a','b'] for args.


Solution

  • args = ['self']
    for C in Three.__mro__:
        if '__init__' in C.__dict__:
            args += inspect.getargspec(C).args[1:]
    

    Edit:

    As a bit of clarification for head scratching people:

    self is returned for all bound methods when calling getargspec so start out with that as a default value. This way we can skip it everywhere (otherwise it would end up in the list multiple times - could also use a set() to avoid this).

    We run through the class' method resolution order list (__mro__).

    Under normal circumstances this list is used to determine which function to call, but in the case of initialization it tells the super().__init__() calls which one is next (which is why it's important that you always call - even if you don't from inherit anything - it or you'll interrupt the chain)

    For every class type we get back, see if it has an __init__ of its own.

    If it does, run the getargspec function on it and add the resulting list of argument names to the initial list, skipping self.

    Note: For python 3+, use getfullargspec instead.