Python检查类的实例

145

有没有办法检查对象是否是类的实例?不是具体类的实例,而是任何类的实例。

我可以检查一个对象不是类、不是模块、不是回溯等等,但我对一个简单的解决方案感兴趣。


8
每个 Python 对象都是某个类(内置或自定义)的实例。 - StoryTeller - Unslander Monica
2
因此,解决方案是函数 def isobject(x): return True。 - Emanuele Paolini
如果我编写from my_module import MyClass,将会得到类对象,而不是类的实例对象;类似地,对于traceback、函数和模块也是如此。inspect 模块包含用于检查这些类型对象的特殊函数,但没有针对类的实例对象的函数。大致上,我想要检测所有对象,对于这些对象 print obj 将会打印 <instance of ...>(如果没有为该类定义特殊的打印形式)。 - exbluesbreaker
一个类只是另一个类的实例(当区分重要时称为元类;通常为type,但任何人都可以定义元类,即使不继承自type)。回溯(traceback)只是traceback的一个实例。函数只是function的一个实例。方法也只是一个类的实例(这取决于你对方法的确切理解)。你需要更具体的说明——或者更好的办法是,告诉我们您的实际问题。 - user395760
12个回答

162

isinstance() 在这里是您的好帮手。它返回一个布尔值,并可用以下方式检查类型。

if isinstance(obj, (int, long, float, complex)):
    print obj, "is a built-in number type"

if isinstance(obj, MyClass):
    print obj, "is of type MyClass"

1
你需要列出所有内置类型并检查是否没有,他说他不想要。 - Youda008
2
这同时也检查对象是否继承自一个类。例如:isinstance(MyClass_instance, object) == true - cowlinator
2
看起来 isinstance(MyClass, type) 返回 True,而 isinstance(MyClass(), type) 返回 False。isinstance(MyClass, object)isinstance(MyClass(), object) 都返回 True。使用 type 的 isinstance 是唯一有效的方法。 - FoolishProtein
FYI PEP 237: 在Python3中,long已被重命名为int。 https://dev59.com/XGUp5IYBdhLWcg3w-LUJ#14904834 - JayRizzo
有没有一种方法可以检查一个对象是否为 numpy.datetime64 对象? - Patrick_Chong

33

你尝试过使用内置函数isinstance() 吗?

你还可以查看hasattr(obj, '__class__'),以查看对象是否是从某个类类型实例化的。


2
这个函数检查具体类的实例,就我所知。我必须将某些类传递给这个函数,例如 isinstance(obj, FooBar),我不能写像 isinstance(obj) 这样的东西。 - exbluesbreaker
1
@exbluesbreaker 除了 isinstance(obj, object) 或者其他适合的类在我们的层次结构中,你有什么想法吗?正如其他人所指出的那样,在Python中,包括数字、回溯、异常等所有东西都是某个类的实例。 - Ber
4
到目前为止,我尝试过的所有类型的变量都满足 hasattr(obj, '__class__') 这一条件。也许更好的检查方式是使用 __name__ - Youda008

13

如果您想检查一个对象是否是用户自定义类的实例而不是内置类型的实例,您可以检查它是否具有__dict__属性。

>>> class A:
...     pass
... 
>>> obj = A()
>>> hasattr(obj, '__dict__')
True
>>> hasattr((1,2), '__dict__')
False
>>> hasattr(['a', 'b', 1], '__dict__')
False
>>> hasattr({'a':1, 'b':2}, '__dict__')
False
>>> hasattr({'a', 'b'}, '__dict__')
False
>>> hasattr(2, '__dict__')
False
>>> hasattr('hello', '__dict__')
False
>>> hasattr(2.5, '__dict__')
False
>>> 

如果您想检查一个实例是否是任何类(无论是用户定义的还是具体的),您可以简单地检查它是否是 Python 中的最终基类object的实例。

class A:
    pass
a = A()
isinstance(a, object)
True
isinstance(4, object)
True
isinstance("hello", object)
True
isinstance((1,), object)
True

相同的测试验证了 def q(): return 1,大多数人会认为它是一个函数,而不是一个类。 - Mark Moretto

7
我曾经遇到了类似的问题,以下方法对我有效:

def isclass(obj):
    return isinstance(obj, type)

2
据我所知,这对于非内置类型无效。 - WestCoastProjects

6

我迟到了。无论如何,我认为这应该可行。

is_class = hasattr(obj, '__name__')

1
很遗憾,它不支持。我使用的是Python 2.7.6版本,我的自定义类的实例没有__name__属性,但函数有。 - Youda008

5
class test(object): pass
type(test)

返回值

<type 'type'>

instance = test()
type(instance)

返回值

<class '__main__.test'>

那么这是区分它们的一种方式。
def is_instance(obj):
    import inspect, types
    if not hasattr(obj, '__dict__'):
        return False
    if inspect.isroutine(obj): 
        return False
    if type(obj) == types.TypeType: # alternatively inspect.isclass(obj)
        # class type
        return False
    else:
        return True

4
或者
import inspect
inspect.isclass(myclass)

2
是的。因此,您可以使用hasattr(obj, '__dict__')obj is not callable(obj)。最初的回答。

没有问题,一个类可以被调用。 - user184868

2
这里有一个小窍门。
if str(type(this_object)) == "<type 'instance'>":
    print "yes it is"
else:
    print "no it isn't"

1
从'object'派生的类,如class MyClass(object)不会返回"<type 'instance'>"而是"<class 'MyClass'>",因此您必须将s.startswith("<class ")添加到条件中。 - Youda008

1

很难确定你需要什么,但也许inspect.isclass(val)是你正在寻找的内容?


2
据我所知,这个检查是用来判断val是否为类对象(而不是类的实例),例如在执行from MyModule import MyClassa = MyClass()之后,inspect.isclass(MyClass)返回True,但inspect.isclass(a)返回False - exbluesbreaker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接