AdvancePython-python中isinstance()、type()以及is、==的区别

在python中,存在这样两组:
isinstance()和type():用来判断某个对象属于某种类型
is和==:用来判断相等的问题,至于是什么相等,我们往后看~

1.isinstace()和type()都是判断某个对象是否属于某个已知的类型,但是它们有如下区别:

  • isinstance() 会认为子类是一种父类类型,考虑继承关系。
  • type() 不会认为子类是一种父类类型,不考虑继承关系。
  • 如果要判断两个类型是否相同,推荐使用 isinstance()。

这下面这个例子中,B继承了A,然后后实例化B得到b,此时b的类型实际上是B,type()显然不认为b是A对象,而isinstance则会往B继承的类去找,并且认为b也属于A类型。

class A:
    pass

class B(A):
    pass

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

print(type(b) is B)     #True
print(type(b) is A)     #false

2.is 和==在判断相等方面有本质的区别:

(1) '=='判断的是两个对象的“值”是否相等,就是说他们的内容是否相等,其内存地址不一样也无妨。
(2) is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。所以说is比较两个条件:内容相同;内存中地址相同。

一个字符串问题的例子:

a1 = 'b'
a2 = 'bb'
a3 = a1 + 'b'
a4 = 'b' + 'b'
print(a2 == a3,id(a2) == id(a3),a2 is a3)  #True False False
print(a2 == a4,id(a2) == id(a4),a2 is a4)  #True True True

注:
#‘b’和’bb’都属于字符串常量,是存储在常量池中的,
#a4经过字符串相加运算之后,发现常量池中已经有了一个’bb’,所以无需再创建,直接指向它即可,所以a4与a2地址一样,值肯定也一样
#a3运算时每次都要去栈中取一次a1变量,再和字符串常量’b’相加,所以不能以为它指向常量池中的’bb’,故a3和a2的地址不一样,但值是相等的

再举一个自定义类的例子:

class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age

stu1 = Student('Tom',18)
stu2 = Student('Tom',18)
stu3 = stu1
print(stu1 == stu2,id(stu1) == id(stu2),stu1 is stu2)#False False False
print(stu1 == stu3,id(stu1) == id(stu3),stu1 is stu3)#True True True

注:
#在python中,一切皆为对象,对象是唯一存在的,也就是说,我们对一个类进行实例化,该实例化后的对象实例都是唯一的,
#所以虽然stu1和stu2实例中的实例变量是一样的,但他们属于不同的对象实例,所以id肯定不相等,其内容也自然不一样;
#而stu3并没有创建一个新的对象,而是直接引用了stu1的对象,所以他们的id是相等的,内容也相等

3.可变类型和不可变类型

在python中,不可变类型为tuple,int,float,str,不可变类型有dict,list,set,自定义的实例等等。
(1) 对于不可变数据类型,变量的值不允许变化,如果我们改变了变量的值,就等于创建了一个新的对象,而原来的变量则等待垃圾回收机制回收它。若有多个变量引用它,在pyton中只会存在一份这样的对象,并且自动记录指向它的变量数

m = 2
n = m
q = 2
m = 3
print(m) #m=3
print(n) #n=2
print(q is n) #True

在这里插入图片描述
在这里插入图片描述

(2) 对于可变数据类型,允许变量的值变化,改变变量的值,而不会创建一个新的对象,变量引用的对象的地址也不会变化。不过对于相同的值的不同对象,在内存中则会存在不同的对象,即每个对象都有自己的地址,相当于内存中对于相同值的对象保存了多份,这里不存在引用计数,是实实在在的对象。

l1 = [1,2,3]
l2 = l1
l3 = [1,2,3]
print(l2)     #[1,2,3]
print(l1 is l2) #True
print(l2 is l3) #False
print(l1 is l3) #False
l1.append(4)
print(l2)     #[1,2,3,4]
print(l2 is l3) #False
print(l1 is l2) #True
print(l1 is l3) #False

在这里插入图片描述
在这里插入图片描述

发布了16 篇原创文章 · 获赞 4 · 访问量 1773

猜你喜欢

转载自blog.csdn.net/qq_40509206/article/details/103486727