Milan
Milan

Reputation: 1740

Python: determine base class of a class_object

I have the following code:

if __name__ == '__main__':

module_name = sys.argv[1]
is_lite = sys.argv[2]

importlib.import_module(module_name)

for name, class_object in inspect.getmembers(sys.modules[module_name]):
    if inspect.isclass(class_object) and not inspect.isabstract(class_object):

        try:
            print "\n\n\n"
            print "Executing: "
            print class_object
            print "\n\n\n"

            instance = class_object()
            instance.execute(is_lite)
        except:
            pass

All objects to be instantiated are actually sub-classes of a class named: Foo which is abstract.

The class_objects returns by inspect contains ALL classes contained in the module, it means that imports are also present in the list, and import are not sub-classes of Foo.

class_object

What I am looking for is simply a method to obtain the following information:

is(class_object, Foo)

This would allow me to get rid of the try catch and have a more logical and robust code.

But so far I found nothing, it seems there no simple way of retrieving the information that is contained into modules returned by the inspect framework.

I also tried to use the builtin issubclass method but it is failling probably because class_object is not an instance of the class but simply a describer of it: class_object is an instance of abc.ABCMeta not of Foo, but will contain all information about Foo.

Thanks for help.

Upvotes: 1

Views: 2875

Answers (3)

Milan
Milan

Reputation: 1740

So far I did not find anything else but to do it this way:

importlib.import_module(module_name)

for _, class_object in inspect.getmembers(sys.modules[module_name]):
    if inspect.isclass(class_object) and not inspect.isabstract(class_object):

        instance = None

        try:
            instance = class_object()

        except:
            pass

        if instance is not None and isinstance(instance, AbstractBaseClass):
            instance.execute(is_lite)

I did not find a simple way to parse 'class_object' content and to extract a String representing the class name of the object.

For information, 'class_object' returns something like this

<class 'name of the actual class'>
   classAttribute: value of the attribute
   ...
   classMethod: <unbound method 'className'.'methodName'>
   ...
   _abc_various_metadatas

Upvotes: 0

Matias Cicero
Matias Cicero

Reputation: 26281

You don't even need to use the inspect module.

You can easily achieve this by checking the __bases__ attribute of a class:

class Foo(object):
    pass

class Bar(Foo):
    pass

print('Bar is child of Foo?', Foo in Bar.__bases__)

__bases__ however, only shows the direct parent of the given class, and not the whole ancestry.

You can actually implement this yourself by iterating over the whole chain of base clases and merging them together in one single tuple:

def get_all_bases(cls, bases=None):
     bases = bases or []
     bases.append(cls)
     for c in cls.__bases__:
         get_all_bases(c, bases)
     return tuple(bases)

Then you'd just:

class Foo(object):
   pass

class Bar(Foo):
   pass

class FooBar(Bar):
   pass

print('FooBar is child of Foo?', Foo in get_all_bases(FooBar))

Upvotes: 2

Attersson
Attersson

Reputation: 4866

Have a look at Python Reflections which can provide information about type, class, attributes and methods of an object.

You are looking for

isinstance(inspect, class_object)

Multiple checks will further ascertain inheritance

Upvotes: 1

Related Questions