Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python -- Check if object is instance of any class from a certain module

Need a way to check if an object is an instance of any class in some particular module.

I know I can do it by explicitly importing every class from that module and checking with a tuple:

from my_module import ClassOne, ClassTwo

>>> isinstance(my_obj, (ClassOne, ClassTwo))
True

But in reality, the module I'm importing from has a TON of classes in it, and seems needlessly verbose to import them all explicitly, use them to build a huge tuple, and type check against it. I've tried a few things to avoid this:

import my_module

# Test my_obj against the module itself
>>> isinstance(my_obj, my_module)
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

# Try to test against a wildcard attribute on my_module
>>> isinstance(my_obj, my_module.*)
SyntaxError: invalid syntax

#Try to build a tuple of clases with iteration to check against
>>> for klass in my_module:
TypeError: 'module' object is not iterable

Is there a way to type check against ALL the classes in my_module, without explicitly naming them in a tuple?

Optional Background Info:
I may be overlooking a better way to approach my problem -- if you are wondering, here's the situation:

We are exporting data from a Google App Engine app to an app we have hosted on Rackspace. We are serializing the data with pickle and then sending it over to our Rackspace server with HTTP Requests.

Some of the data in the Google App Engine database is of GAE-specific data-types, imported from google.appengine.api.datastore_types. If any of these data types go across the wire to our Rackspace server, they will raise an error depickling, because our Rackspace app doesn't have the required GAE libraries. So, on the way out of GAE, I'm checking to see if any of the outgoing objects have a type from google.appengine.api.datastore_types. If they do, I either convert them to a builtin data-type or I delete the field off the object.

like image 617
Clay Wardell Avatar asked Jan 28 '13 20:01

Clay Wardell


People also ask

How do you check if an object is from a certain class Python?

In Python, the built-in functions type() and isinstance() help you determine the type of an object. type(object) – Returns a string representation of the object's type. isinstance(object, class) – Returns a Boolean True if the object is an instance of the class, and False otherwise.

What method is used to check if an object is an instance of a certain class in Python?

Syntax of isinstance() function Return: true if the object is an instance or subclass of a class, or any element of the tuple false otherwise. If class info is not a type or tuple of types, a TypeError exception is raised. Example 1: In this example, we will see test isinstance() for the class object.

How do you check if an object is an instance of a particular type?

The JavaScript instanceof operator is used to check the type of an object at the run time. It returns a boolean value(true or false). If the returned value is true, then it indicates that the object is an instance of a particular class and if the returned value is false then it is not.

How do I check if an object is an instance of a given class or of a subclass of it?

The isinstance() method checks whether an object is an instance of a class whereas issubclass() method asks whether one class is a subclass of another class (or other classes).


2 Answers

You can use inspect.getmembers to get all the classes in your module:

inspect.getmembers(my_module,inspect.isclass) 

This will return a list of name-class pairs. You just want the classes:

my_module_classes = tuple(x[1] for x in inspect.getmembers(my_module,inspect.isclass)) 

One thing that I managed to overlook when I initially wrote this answer is the ability to check a class's __module__ attribute. You might be able to get away with checking if the __module__ is what you expect it to be:

from somewhere import module  if getattr(obj, '__module__', None) == module.__name__:     # obj is from module. 

This is likely to be cheaper than isinstance checking against a large list of class names.

like image 143
mgilson Avatar answered Oct 07 '22 11:10

mgilson


I have used @mgilson simple solution:

from somewhere import module  if getattr(obj, '__module__', None) == module.__name__:     # obj is from module. 

and noticed that if you have a tree of modules, and you want to make sure it comes from the base module, you have to do:

from somewhere import module  if getattr(obj, '__module__', None).split('.')[0] == module.__name__:     # obj is from module. 

But if your object is from a built-in it'll rise an exception, so I'd:

from somewhere import module  module_tree = getattr(obj, '__module__', None) parent = module_tree.split('.')[0] if module_tree else None  if parent == module.__name__:     # obj is from module. 
like image 24
Rodrigo E. Principe Avatar answered Oct 07 '22 09:10

Rodrigo E. Principe