如何检查变量是否为类?


236

我想知道如何检查变量是否是类(不是实例!)。

我试图使用该函数isinstance(object, class_or_type_or_tuple)来执行此操作,但我不知道类将具有哪种类型。

例如,在以下代码中

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

我试图class???代替“ ” ,但我意识到这class是python中的关键字。

Answers:


335

更好的是:使用该inspect.isclass功能。

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

>>> x = X()
>>> isinstance(x, X)
True
>>> y = 25
>>> isinstance(y, X)
False

7
如果您还想inspect.isclass返回True要检查的对象是否是类实例,请使用inspect.isclass(type(Myclass()))
michaelmeyer

8
比什么更好:)?
疯狂物理学家,2016年

8
@michaelmeyer type(whatever)始终返回作为类的对象,因此此检查是多余的。如果没有,则无法实例化whatever,因此您一开始就无法执行检查。
a_guest

对我不起作用。将python3与snakemake一起使用时,type(snakemake.utils)返回<class 'module'>,然后inspect.isclass(snakemake.utils)返回False
tedtoal '18

3
那是因为snakemake.util模块不是类吗?
本杰明·彼得森

44

inspect.isclass可能是最好的解决方案,并且很容易看到它是如何实现的

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

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

5
记住import types

13
types.ClassType在Python 3中不再需要(并且已删除)。
kawing-chiu

这确实与新式类完全不工作....即使在蟒蛇2.不要单独使用该解决方案
埃里克Aronesty

那是从检查模块中获取的,所以我怀疑它不起作用。例如,使用Python2.7进行检查很简单In [8]: class NewStyle(object): ...: pass ...: In [9]: isinstance(NewStyle, (type, types.ClassType)) Out[9]: True
andrea_crotti

这是Python 2实现,必须处理旧样式和新样式的类。Python 3将其简化为isinstance(object, type)。需要注意的是对象,如intliststr,等都是同样的类,所以你不能用这个来区分在Python定义自定义类内置的C代码定义的类
马丁·皮特斯

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

1
嗯...很好的答案,但是当我在Foo类上输入type(Foo)时,它说的是<type'classobj'>,而不是<type'type'>。我认为差异是由于X是从对象继承而来的,而Foo不是。这有其他区别吗?谢谢。
jeeyoungk

6
它不适用于老式类:'class Old:pass' 'isinstance(Old, type) == False',但inspect.isclass(Old) == True
jfs

1
@jeeyoungk:您不是在“假设差异来自...”,而是在代码中实际读取它。对象的子类(“新样式”)具有所需的属性,就像您在此处看到的一样。
S.Lott

12
这是提示-因为这适用于新样式的类,所以不要使用旧样式的类。没有必要使用老式类。
S.Lott

isinstance(e,f)E是实例化的对象,F是类对象。
德克斯特(Dexter)2015年

24
isinstance(X, type)

返回Trueif X是class,False如果不是,则返回。


3
即使X是一个类,我也会得到False。
Mads Skjern 2012年

6
这仅适用于新样式类。旧样式类的类型为“ classobj”。因此,如果您使用的是旧样式类,则可以执行以下操作:导入类型isinstance(X,types.ClassType)
Charles L.

2
这似乎与S. Lott's answer年龄大了四年。
伊桑·弗曼

5

此检查与Python 2.x和Python 3.x兼容。

import six
isinstance(obj, six.class_types)

这基本上是一个包装函数,执行与andrea_crotti答案中相同的检查。

例:

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


1

最简单的方法是使用inspect.isclass投票最多的答案中的内容。
实现细节可以在python2 inspectpython3 inspect中找到
对于新型类:isinstance(object, type)
对于老式类:isinstance(object, types.ClassType)
em,对于老式类,它正在使用types.ClassType,这是来自types.py的代码:

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

1

本杰明·彼得森(Benjamin Peterson)inspect.isclass()对于这项工作的使用是正确的。但是请注意,您可以使用内置函数issubclass来测试Class对象是否是特定对象Class,因此是否是隐式对象。根据您的用例,这可能更像pythonic。Class

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

然后可以这样使用:

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

-2

这里已经有一些可行的解决方案,但这是另一个解决方案:

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

types.ClassType已在Python 3中删除
Beau Barker
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.