Reputation: 3665
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
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
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
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
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
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
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
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
Upvotes: 1
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
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
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
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
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
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
Reputation: 392010
>>> class X(object):
... pass
...
>>> type(X)
<type 'type'>
>>> isinstance(X,type)
True
Upvotes: 80