143

Is there any way to check if object is an instance of a class? Not an instance of a concrete class, but an instance of any class.

I can check that an object is not a class, not a module, not a traceback etc., but I am interested in a simple solution.

peterh
  • 11,875
  • 18
  • 85
  • 108
exbluesbreaker
  • 2,160
  • 3
  • 18
  • 30
  • 8
    Every python object is an instance of some class (built-in or otherwise). – StoryTeller - Unslander Monica Jan 27 '13 at 16:25
  • 2
    So the solution is the function def isobject(x): return True – Emanuele Paolini Jan 27 '13 at 16:28
  • If i write `from my_module import MyClass` will be class object, not instance of class, similiarly for traceback, function, module. `inspect` module contains special checking functions for this type of objects, but no function for instances of classes. Roughly, i want to detect all objects, for which `print obj` will print `` (if no special printing defined for class) – exbluesbreaker Jan 27 '13 at 16:50
  • A class is just an instance of another class (called metaclass when the distinction matters; commonly `type` but anyone can define a metaclass, IIRC even without inheriting from `type`). A traceback is just an instance of `traceback`. A function is just an instance of `function`. A method is just an instance of a class too (which depends on what exactly you mean by method). You'll have to be more specific -- or even better, just [tell us your *actual* problem](http://meta.stackexchange.com/q/66377). –  Jan 27 '13 at 17:35

12 Answers12

162

isinstance() is your friend here. It returns a boolean and can be used in the following ways to check types.

if isinstance(obj, (int, long, float, complex)):
    print obj, "is a built-in number type"

if isinstance(obj, MyClass):
    print obj, "is of type MyClass"
starball
  • 20,030
  • 7
  • 43
  • 238
Matt Alcock
  • 12,399
  • 14
  • 45
  • 61
  • you would have to list ALL of the built-in types and check if it isn't any, which he says he doesn't want – Youda008 Sep 12 '16 at 09:56
  • 2
    This also checks if the object is inherits from a class. E.g. `isinstance(MyClass_instance, object) == true`. – cowlinator May 07 '20 at 04:00
  • 2
    Looks like `isinstance(MyClass, type)` returns True while `isinstance(MyClass(), type)` returns False. Both `isinstance(MyClass, object)` and `isinstance(MyClass(), object)` return True. Isinstance with type is the only one that seems to work – FoolishProtein Nov 29 '20 at 16:24
  • FYI PEP 237: python3, `long` was renamed to `int`. https://stackoverflow.com/a/14904834/1896134 – JayRizzo Jun 27 '22 at 23:37
  • Is there a way to check if an object is a `numpy.datetime64` object? – Patrick_Chong Aug 25 '22 at 08:47
32

Have you tried isinstance() built in function?

You could also look at hasattr(obj, '__class__') to see if the object was instantiated from some class type.

Ber
  • 40,356
  • 16
  • 72
  • 88
  • 2
    This fucntion check instances of concrete class, for all i know. I must pass some class to this function, e.g. `isinstance(obj,FooBar)` i can't write something like `isinstance(obj)` – exbluesbreaker Jan 27 '13 at 16:36
  • 1
    @exbluesbreaker What about `isinstance(obj, object)` or some other suitable class high up in our hierarchy? As others have ponted our, everything in Python is an instance of some class, including numbers, tracebacks, exceptions, etc. – Ber Jan 28 '13 at 09:54
  • 4
    So far `hasattr(obj, '__class__')` was always true for all types of variables i tried. Maybe `__name__` would be better to check. – Youda008 Sep 12 '16 at 10:01
12

If you want to check that an object is of a user defined class and not instance of concrete built-in types you can check if it has __dict__ attribute.

>>> class A:
...     pass
... 
>>> obj = A()
>>> hasattr(obj, '__dict__')
True
>>> hasattr((1,2), '__dict__')
False
>>> hasattr(['a', 'b', 1], '__dict__')
False
>>> hasattr({'a':1, 'b':2}, '__dict__')
False
>>> hasattr({'a', 'b'}, '__dict__')
False
>>> hasattr(2, '__dict__')
False
>>> hasattr('hello', '__dict__')
False
>>> hasattr(2.5, '__dict__')
False
>>> 

If you are interested in checking if an instance is an object of any class whether user defined or concrete you can simply check if it is an instance of object which is ultimate base class in python.

class A:
    pass
a = A()
isinstance(a, object)
True
isinstance(4, object)
True
isinstance("hello", object)
True
isinstance((1,), object)
True
Rohit
  • 3,659
  • 3
  • 35
  • 57
7

I had a similar problem at this turned out to work for me:

def isclass(obj):
    return isinstance(obj, type)
N.C. van Gilse
  • 131
  • 2
  • 3
6

I'm late. anyway think this should work.

is_class = hasattr(obj, '__name__')
ellethee
  • 161
  • 2
  • 8
  • 1
    Unfortunately it doesn't. I have Python 2.7.6 and instances of my defined classes doesn't have `__name__`, but functions have. – Youda008 Sep 12 '16 at 10:49
5
class test(object): pass
type(test)

returns

<type 'type'>

instance = test()
type(instance)

returns

<class '__main__.test'>

So that's one way to tell them apart.

def is_instance(obj):
    import inspect, types
    if not hasattr(obj, '__dict__'):
        return False
    if inspect.isroutine(obj): 
        return False
    if type(obj) == types.TypeType: # alternatively inspect.isclass(obj)
        # class type
        return False
    else:
        return True
user2682863
  • 3,097
  • 1
  • 24
  • 38
4

or

import inspect
inspect.isclass(myclass)
Farshid Ashouri
  • 16,143
  • 7
  • 52
  • 66
2

It's a bit hard to tell what you want, but perhaps inspect.isclass(val) is what you are looking for?

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 1
    As far as i know, this one check, if val is class object (not instance of class), e.g. after `from MyModule import MyClass` and `a = MyClass()` `inspect.isclass(MyClass)` returns `True`, but `inspect.isclass(a)` returns `False`. – exbluesbreaker Jan 28 '13 at 16:44
2

Here's a dirt trick.

if str(type(this_object)) == "<type 'instance'>":
    print "yes it is"
else:
    print "no it isn't"
f.rodrigues
  • 3,499
  • 6
  • 26
  • 62
  • 1
    Classes, that are derived from 'object' like `class MyClass(object)` do not return `""` but `""`, so you must add `s.startswith(" – Youda008 Sep 12 '16 at 11:53
2

Yes. Accordingly, you can use hasattr(obj, '__dict__') or obj is not callable(obj).

Jonathan Gagne
  • 4,241
  • 5
  • 18
  • 30
seaky
  • 21
  • 1
1

Is there any way to check if object is an instance of a class? Not an instance of a concrete class, but an instance of any class.

I can check that an object is not a class, not a module, not a traceback etc., but I am interested in a simple solution.

One approach, like you describe in your question, is a process of exclusion, check if it isn't what you want. We check if it's a class, a module, a traceback, an exception, or a function. If it is, then it's not a class instance. Otherwise, we return True, and that's potentially useful in some cases, plus we build up a library of little helpers along the way.

Here is some code which defines a set of type checkers and then combines them all to exclude various things we don't care about for this problem.

from types import (
    BuiltinFunctionType,
    BuiltinMethodType,
    FunctionType,
    MethodType,
    LambdaType,
    ModuleType,
    TracebackType,
)
from functools import partial
from toolz import curry
import inspect
    
def isfunction(variable: any) -> bool:
    return isinstance(
        variable,
        (
            BuiltinFunctionType,
            BuiltinMethodType,
            FunctionType,
            MethodType,
            LambdaType,
            partial,
            curry
        ),
    )
    
isclass = inspect.isclass
    
def ismodule(variable: any) -> bool:
   return isinstance(variable, ModuleType)
    
    
def isexception(variable: any) -> bool:
    return isinstance(variable, Exception)
    
    
def istraceback(variable: any) -> bool:
    return isinstance(variable, TracebackType)
    
    
def isclassinstance(x: any) -> bool:
    if isfunction(x) or isclass(x) or ismodule(x) or istraceback(x) or isexception(x):
        return False
    return True

keep in mind, from a hella abstract perspective, everything is a thing, even categories of things or functions ... but from a practical perspective, this could help avoid mistaking MyClass for my_class_instance (the python community also does this informally with PascalCase vs snake_case)

we could improve this

0

Had to deal with something similar recently.

import inspect

class A:
    pass

def func():
    pass

instance_a = A()

def is_object(obj):
     return inspect.isclass(type(obj)) and not type(obj) == type

is_object(A)          # False
is_object(func)       # False
is_object(instance_a) # True
Ben Hoff
  • 1,058
  • 1
  • 11
  • 24