老规矩,还是先看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

class A:
pass


class B(A):
pass


b = B()
print(isinstance(b, B))
print(isinstance(b, A))

# 运行结果:
True
True

很容易理解因为isinstance判断的是继承关系,我们再来看一下type,不过我需要说明一下这个is 和==的区别:is用来判断这两个对象是不是同一个对象,就是判断id是否相同;而== 是用来判断这两个对象的value是不是相等。我们看一段代码,加深一下印象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A:
pass

class B(A):
pass


b = B()

print(id(b), id(B), id(A))
print(b is B) # 判断这两个对象是不是同一个对象,就是判断id是否相同
print(b is A)

# 输出结果:
10722864 16500152 16499680
False
False

因此:is同一性运算符:比较判断两个对象是否相同,id做为判断因素。我们往下看:

1
2
3
4
5
6
7
print(b == B)
print(b == A)


# 输出结果:
False
False

因此:**==比较操作符:用来比较两个对象是否相等,value做为判断因素**。

接下来说一下type,我们都是判断某某是某某,而不是值,所以都应该使用is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class A:
pass


class B(A):
pass


class C(B):
pass


b = B()
c = C()

print(type(b) is B)
print(type(b) is A)

print(type(c) is C)
print(type(c))
print(C)
print(id(type(c)))
print(id(c), id(C))

# 输出结果是:
True
False
True
<class '__main__.C'>
<class '__main__.C'>
15112080
14917168 15112080

type两种用法:第一生成一个类,第二返回某个对象的类型。这里用第二种用法,所以很好理解对吧,c是C类实例化出来的对象,那么c返回的就是这个C类,(type(c)已经指向了C就不可能指向这个B,BC是两个不同的对象)这也就是type(c) is C为True的原因。

所以,我们平常就尽量使用isinstance,这样可以避免一些不必要的错误。