1

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.

Vy.Iv
  • 829
  • 2
  • 8
  • 17

2 Answers2

2

You may want to read up on python Mixins first.

In general, it's pretty bad form to use multiple inheritance using two classes with conflicting names. The class on the far left is always prioritized, leading to some funky things for methods from the other classes that use the overwritten method.

If you want an object with a variable number of args/kwargs, you should just specify that.

class Foo(object):

    def __init__(self, **kwargs):
        for k, v in kwargs.iteritems():
            setattr(self, k, v)
Community
  • 1
  • 1
Thtu
  • 1,992
  • 15
  • 21
2
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.

Blizz
  • 8,082
  • 2
  • 33
  • 53
user2683246
  • 3,399
  • 29
  • 31