How to check whether a variable is a class or not?
Question:
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.
Answers:
>>> class X(object):
... pass
...
>>> type(X)
<type 'type'>
>>> isinstance(X,type)
True
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
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“
isinstance(X, type)
Return True
if X
is class and False
if not.
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))
There are some working solutions here already, but here’s another one:
>>> import types
>>> class Dummy: pass
>>> type(Dummy) is types.ClassType
True
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)
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
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
There is an alternative way to check it:
import inspect
class cls():
print(None)
inspect.isclass(cls)
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
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__
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'
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.
>>> class X(object):
... pass
...
>>> type(X)
<type 'type'>
>>> isinstance(X,type)
True
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
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“
isinstance(X, type)
Return True
if X
is class and False
if not.
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))
There are some working solutions here already, but here’s another one:
>>> import types
>>> class Dummy: pass
>>> type(Dummy) is types.ClassType
True
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)
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
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
There is an alternative way to check it:
import inspect
class cls():
print(None)
inspect.isclass(cls)
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
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__
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'