📜  Python中的类型和isinstance

📅  最后修改于: 2022-05-13 01:55:50.472000             🧑  作者: Mango

Python中的类型和isinstance

输入Python

Python有一个称为 type 的内置方法,通常在确定运行时程序中使用的变量类型时会派上用场。

    如果将单个参数(对象)传递给内置的 type(),它会返回给定对象的类型。如果传递了三个参数(名称、基数和字典),则返回一个新类型对象。
    句法:
type(object)
type(name, bases, dict)
  1. type() 带有单个对象参数
    # Python code type() with a single object parameter
    x = 5
    s = "geeksforgeeks"
    y = [1,2,3]
    print(type(x))
    print(type(s))
    print(type(y))
    

    输出:

    class 'int'
    class 'str'
    class 'list'
    
  2. type() 带有名称、基数和 dict 参数
    # Python code for type() with a name, 
    # bases and dict parameter
      
    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}
    

    如果需要检查对象的类型,建议使用Python isinstance()函数。这是因为 isinstance()函数还会检查给定对象是否是子类的实例。

实例()

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

句法:

isinstance(object, classinfo) 
The isinstance() takes two parameters:
object : object to be checked
classinfo : class, type, or tuple of classes and types

返回值:
如果对象是类的实例或子类,则为 true,否则为false 。如果类信息不是类型或类型的元组,则会引发 TypeError 异常。

# Python code for  isinstance()
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() 与 isinstance()

人们犯的一个基本错误是使用 type()函数,其中 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

参考链接: