jeeyoungk
jeeyoungk

Reputation: 3665

How to check whether a variable is a class or not?

I was wondering how to check whether a variable is a class (not an instance!) or not.

I've tried to use the function isinstance(object, class_or_type_or_tuple) to do this, but I don't know what type a class would have.

For example, in the following code

class Foo:
    pass

isinstance(Foo, **???**) # i want to make this return True.

I tried to substitute "class" with ???, but I realized that class is a keyword in python.

Upvotes: 363

Views: 321379

Answers (14)

user2675933
user2675933

Reputation: 1

The short answer is that in Python the type of class is type. If it is an object, then the type will be something else. Strangely enough after playing around with it, I have discovered that below is all you need. Why there is not a built-in method for one line of code, I don't know. The image below was a terminal screenshot of what all I tried, since I cannot upload pictures yet. I will give you the gist of it:

class MyClass:
   def __init__(self, x):
       self.x = x;

myobj = MyClass(2);
myobj.x;#2
isinstance(myobj, MyClass);#True
isinstance(MyClass, MyClass);#False
MyClass == MyClass;#True
isinstance(MyClass, str);#False
type(myobj) == object;#False
type(myobj);#<class '__main__.MyClass'>
myobj.__class__#<class '__main__.MyClass'>
a = 10;
a.__class__#<class 'int'>
MyClass.__class__#<class 'type'>
type(MyClass);#<class 'type'>
def isClass(val): return (type(val) == type);
isClass(MyClass);#True
isClass(None);#False
isClass(10);#False

DONE WITH IMAGE OF TERMINAL CONTENTS ON PYTHON SHELL. ANSWER BELOW:

def isClass(val): return (type(val) == type);

terminal picture but contents of what I tried is above

Upvotes: 0

Jimmy Chen
Jimmy Chen

Reputation: 315

Check with type(X) is type

>>> type(Exception) is type
True

>>> type(3) is type
False

>>> class Dummy: pass
>>> type(Dummy) is type
True

Inspired by S.Lott's anwser.

Upvotes: 0

Anthony M.
Anthony M.

Reputation: 146

The simplest solution I found and use successfully is:

 def isclass(cls):
    return str(type(cls)).startswith("<class") and hasattr(cls, '__weakref__')

Upvotes: 1

Ryan H.
Ryan H.

Reputation: 2593

If you are using a class decorator, inspect.isclass() will not work since the class is wrapped by a function. Instead, use inspect.unwrap() first, then test with inspect.isclass().

Example:

import functools
import inspect

def class_decorator(cls):
    @functools.wraps(cls)
    def wrapper(*args, **kwargs):
        return cls(*args, **kwargs)
    return wrapper

@class_decorator
class Spam:
    pass

print(inspect.isclass(Spam)) # False
print(type(Spam)) # class 'function'

print(inspect.isclass(inspect.unwrap(Spam))) # True
print(inspect.unwrap(Spam)) # class 'Spam'

Upvotes: 1

andrea_crotti
andrea_crotti

Reputation: 3100

The inspect.isclass is probably the best solution, and it's really easy to see how it's actually implemented

def isclass(obj):
    """Return true if the obj is a class.

    Class objects provide these attributes:
        __doc__         documentation string
        __module__      name of module in which this class was defined"""
    return isinstance(obj, (type, types.ClassType))

Upvotes: 56

Ben Law
Ben Law

Reputation: 58

In some cases (depending on your system), a simple test is to see if your variable has a __module__ attribute.

if getattr(my_variable,'__module__', None):
    print(my_variable, ".__module__ is ",my_variable.__module__)
else:
    print(my_variable,' has no __module__.')

int, float, dict, list, str etc do not have __module__

Upvotes: -1

Kirro Smith
Kirro Smith

Reputation: 91

Well, inspect.isclass is not working for me, instead, try this

class foo:
    pass

var = foo()

if str(type(var)).split(".")[0] == "<class '__main__":
    print("this is a class")
else:
    print(str(type(var)).split(".")[0])

So basically, type(var) is <class 'a type'>

Example: <class 'int' But, when var is a class, it will appear something like <class '__main__.classname'>

So we split the string into <class '__main__ and we compare using if, if the string fit perfectly then it's a class

enter image description here

Upvotes: 1

Benjamin Peterson
Benjamin Peterson

Reputation: 20580

Even better: use the inspect.isclass function.

>>> import inspect
>>> class X(object):
...     pass
... 
>>> inspect.isclass(X)
True

>>> x = X()
>>> isinstance(x, X)
True
>>> inspect.isclass(x)
False

Upvotes: 516

omni
omni

Reputation: 4525

Benjamin Peterson is correct about the use of inspect.isclass() for this job. But note that you can test if a Class object is a specific Class, and therefore implicitly a Class, using the built-in function issubclass. Depending on your use-case this can be more pythonic.

from typing import Type, Any
def isclass(cl: Type[Any]):
    try:
        return issubclass(cl, cl)
    except TypeError:
        return False

Can then be used like this:

>>> class X():
...     pass
... 
>>> isclass(X)
True
>>> isclass(X())
False

Upvotes: 4

Sergey
Sergey

Reputation: 647

This check is compatible with both Python 2.x and Python 3.x.

import six
isinstance(obj, six.class_types)

This is basically a wrapper function that performs the same check as in andrea_crotti answer.

Example:

>>> import datetime
>>> isinstance(datetime.date, six.class_types)
>>> True
>>> isinstance(datetime.date.min, six.class_types)
>>> False

Upvotes: 8

lyu.l
lyu.l

Reputation: 302

simplest way is to use inspect.isclass as posted in the most-voted answer.
the implementation details could be found at python2 inspect and python3 inspect.
for new-style class: isinstance(object, type)
for old-style class: isinstance(object, types.ClassType)
em, for old-style class, it is using types.ClassType, here is the code from types.py:

class _C:
    def _m(self): pass
ClassType = type(_C)

Upvotes: 1

Ztyx
Ztyx

Reputation: 14959

There are some working solutions here already, but here's another one:

>>> import types
>>> class Dummy: pass
>>> type(Dummy) is types.ClassType
True

Upvotes: -2

JV.
JV.

Reputation: 2698

class Foo: is called old style class and class X(object): is called new style class.

Check this What is the difference between old style and new style classes in Python? . New style is recommended. Read about "unifying types and classes"

Upvotes: 1

S.Lott
S.Lott

Reputation: 392010

>>> class X(object):
...     pass
... 
>>> type(X)
<type 'type'>
>>> isinstance(X,type)
True

Upvotes: 80

Related Questions