English 中文(简体)
如何检查变量是否为类?
原标题:
  • 时间:2008-12-28 03:08:05
  •  标签:

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

我尝试使用函数 isinstance(object, class_or_type_or_tuple) 来做这件事,但我不知道一个类会有什么类型。

例如,在以下代码中

class Foo:
    pass

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

我试图用???替换"class",但我意识到class是Python的关键字。

最佳回答

更好的方法是使用inspect.isclass函数。

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

>>> x = X()
>>> isinstance(x, X)
True
>>> inspect.isclass(x)
False
问题回答
>>> class X(object):
...     pass
... 
>>> type(X)
<type  type >
>>> isinstance(X,type)
True

inspect.isclass可能是最好的解决方案,而且非常容易看出它是如何实现的。

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))
isinstance(X, type)

如果X是类,则返回True,否则返回False

这个检查与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

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

然后可以像这样使用:

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

类Foo:被称为旧式类,而类X(object):被称为新式类。

请查看此链接:Python中旧版和新版类有什么区别?。推荐使用新版类。请阅读 "类型和类的统一" 的内容。

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)

好的,inspect.isclass 对我没有起作用,相反,请尝试这个。

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])

基本上,type(var)<class a type >

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

所以我们将字符串分割成<class __main__,并使用if进行比较,如果字符串完全匹配,则为类。

将此翻译成中文:enter image description here 无法翻译为中文,因为这是一个图片的代码。

如果您正在使用类修饰符,inspect.isclass()将不起作用,因为该类被一个函数包装起来。 相反,请先使用inspect.unwrap(),然后使用inspect.isclass()进行测试。

例子:

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 

有另一种方法来检查它:

import inspect

class cls():
     print(None)

inspect.isclass(cls)

参考:https://www.kite.com/python/docs/inspect.isclass

在某些情况下(取决于您的系统),一个简单的测试是查看您的变量是否具有 __module__ 属性。

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等都没有__module__。

这里已经有一些可以工作的解决方案了,但这是另一种:

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




相关问题
热门标签