Python 中的 type() 和 isinstance()

yufei       5 年, 8 月 前       845

Python 有一个名为 type() 的内置方法,通常用于在运行时动态的计算变量的类型

如果传递给内置的 type() 方法传递单一的参数 ( 通常是一个对象 ),则返回给定参数 ( 对象 ) 的类型,如果传递了三个参数 ( name, basesdict ),则会返回一个新的类型对象

type() 语法

所以,type() 函数的语法格式如下

type(object)

type(name, bases, dict)

示例

  1. 单个对象参数的 type()
    x = 5
    s = "geeksforgeeks"
    y = [1,2,3]
    print(type(x))
    print(type(s))
    print(type(y))
    

输出结果如下

    class 'int'
    class 'str'
    class 'list'
  1. 三个参数的 type()

    o1 = type('X', (object,), dict(a='Foo', b=12))
    
    print(type(o1))
    print(vars(o1))
    
    class test:
          a = 'Foo'
      b = 12
    
    o2 = type('Y', (test,), dict(a='Foo', b=12))
    print(type(o2))
    print(vars(o2))
    

    输出结果如下

    {'b': 12, 'a': 'Foo', '__dict__': , '__doc__': None, '__weakref__': }
    {'b': 12, 'a': 'Foo', '__doc__': None}
    

如果需要检查某个对象是否是某个类型的实例,则建议使用 Pythonisinstance() 函数,因为 isinstance() 函数还可以检查给定对象是否是子类的实例

isinstance()

isinstance() 函数检查某个对象 ( object,第一个参数 ) 是否是某个类 ( classinfo , 第二个参数 ) 的实例或子类

语法

isinstance() 函数的语法格式如下

isinstance(object, classinfo)

参数说明

参数 说明
object 需要检查的对象
classinfo 类、type 或元组

返回值

如果对象是类的实例或子类,或者为元组的任何元素,则返回 True,否则返回 False。 如果参数 classinfo 不是一个类型,或由多个类型组成的元组,则会引发 TypeError 异常

示例

class Test:
    a = 5

TestInstance = Test()

print(isinstance(TestInstance, Test))
print(isinstance(TestInstance, (list, tuple)))
print(isinstance(TestInstance, (list, tuple, Test)))

输出结果如下

True
False
True

type() vs isinstance()

可能大家经常犯的一个基本错误是使用 type() 函数,其实 isinstance() 更合适

  • 如果你想要检查对象是否属于某个类型,则需要使用 isinstance() ,因为它检查第一个参数中传递的对象是否是第二个参数中传递的任何类型对象的类型

    因此,isinstance() 在子类化和旧式类中同样能够按预期工作,所有类都具有遗留类型对象实例

  • type(),从某些方面说,只会返回一个对象的类型对象,并且当你在两边使用完全相同的类型对象进行比较时,只会返回 True

    Python 中,使用的是 Duck Typing ( 类型检查延迟到运行时,并通过动态类型或反射实现 ) , 而不是检查对象的类型

    #Python code to illustrate duck typing
    
    class User(object):
        def __init__(self, firstname):
            self.firstname = firstname
    
        @property
        def name(self):
            return self.firstname
    
    class Animal(object):
        pass
    
    class Fox(Animal):
        name = "Fox"
    
    class Bear(Animal):
        name = "Bear"
    
    # Use the .name attribute (or property) regardless of the type
    for a in [User("Geeksforgeeks"), Fox(), Bear()]:
        print(a.name)
    

    输出结果如下

    Geeksforgeeks
    Fox
    Bear
    
  • 不使用 type() 的另一个原因是它缺乏对继承的支持

    #python code to illustrate the lack of
    #support for inheritance in type()
    
    class MyDict(dict):
        """A normal dict, that is always created with an "initial" key"""
        def __init__(self):
            self["initial"] = "some data"
    
    d = MyDict()
    print(type(d) == dict)
    print(type(d) == MyDict)
    
    d = dict()
    print(type(d) == dict)
    print(type(d) == MyDict)
    

    输出结果如下

    False
    True
    True
    False
    

    MyDict 类具有 dict 的所有属性,没有任何新方法。它的行为与字典完全相同。但是 type() 不会返回预期的结果

    在这种情况下,最好使用 isinstance(),因为它会给出预期的结果

    #python code to show isintance() support
    #inheritance
    class MyDict(dict):
        """A normal dict, that is always created with an "initial" key"""
        def __init__(self):
            self["initial"] = "some data"
    
    d = MyDict()
    print(isinstance(d, MyDict))
    print(isinstance(d, dict))
    
    d = dict()
    print(isinstance(d, MyDict))
    print(isinstance(d, dict))
    

    输出结果如下

    True
    True
    False
    True
    

结束语

其实吧,一开始我也容易混淆 type()isinstance() 两个内建方法,但后面时候的时候多了,慢慢的就记住了它们的区别

简化了的说,type() 返回参数的类型,而 isinstance() 则检查第一个参数是否是第二个参数的实例或子类

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.