开发者学堂课程【Python入门 2020年版:__eq__方法的使用 】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/639/detail/10371
__eq__方法的使用
内容介绍:
一、运算符相关的魔法方法
二、身份运算符 is
三、运算符相关的魔法方法
一、运算符相关的魔法方法
新建 python 文件,名为 09- 运算符相关的魔法方法
(1)p1、p2 是同一个对象吗?
在创建对象的时候,这两对象不一样,都是通过调用 __new__方法申请内存空间,申请的两个空间是不一样的。
当两个对象都申请了空间之后,这两个的关系就在于它们的数据内容是相同的。就在内存中占了两个空间,两个就是属于数据相同而已,具体关系图如下:
(2)怎样比较两个对象是否为一个对象?
比较的是内存地址,加入语句 print(‘0x%X’ % id(p1))、print(‘0x%X’ % id(p2))
添加代码:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Person(‘zhangsan’,18)
p2 = Person(‘zhangsan’,18)
print(‘0x%X’ % id(p1))
print(‘0x%X’ % id(p2))
运行结果如下:
可以看到是两个不同的地址,这就说明这两个不是一个对象
申请的内存大小不用考虑,这是属于内存管理的事情,在这不做解释。
二、身份运算符 is
它用来判断两个是不是同一个对象,是的话就是 true,否则就是 false。
(1)使用语句 print(p1 is p2)
代码内容:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Person(‘zhangsan’,18)
p2 = Person(‘zhangsan’,18)
print(‘0x%X’ % id(p1))
print(‘0x%X’ % id(p2))
print(p1 is p2)
运行结果如下:
(2)判断两个 num1、num2 相等?
加入语句:
num1 = [1,2,3]
num2 = [1,2,3]
num1 is num2
代码内容:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Person(‘zhangsan’,18)
p2 = Person(‘zhangsan’,18)
print(‘0x%X’ % id(p1))
print(‘0x%X’ % id(p2))
print(p1 is p2)
num1 = [1,2,3]
num2 = [1,2,3]
print(num1 is num2)
运行结果如下:
依旧是 false,这是两个链表,所占的内存不同。只是不同的数据空间但所存储的内容是一样的,是不同的两个对象。
(3)num1 == num2
输入语句 print(num1 == num2)
代码内容:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
p1 = Person(‘zhangsan’,18)
p2 = Person(‘zhangsan’,18)
print(‘0x%X’ % id(p1))
print(‘0x%X’ % id(p2))
print(p1 is p2)
num1 = [1,2,3]
num2 = [1,2,3]
print(num1 is num2)
print(num1 ==num2)
运行结果如下:
结果是 true
is 是用来比较两个对象的内存地址,而==是比较值的
比较 p1、p2
这个原因是由于从表象上来看==是用来比较值的,但它会调用对象的__eq__方法,获取这个方法的比较结果。
三、__eq__方法
== 在表面上看的时候,就是在比较值。实际上是调用__eq__方法,比如像链表list,这个类不是我们书写的,是系统自动写的代码,系统会重写__eq__方法,如下图。
这个__eq__方法会将两个数据一个、一个进行比较,有一出不一样就会返回 False。也就是 == 本质上比较的是__eq__方法。
所以在之前的例子中,p1 = p2 的本质是调用 p1.__eq__(p2)
__eq__方法如果不重写,默认的就是比较内存地址
现在想将年龄和名字一样在==时认为是一个对象,需要进行下面的操作。加入代码
def __eq__(self,other):
print(‘__eq__方法被调用了,other=’,other)
代码内容:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __eq__(self,other):
print(‘__eq__方法被调用了,other=’,other)
p1 = Person(‘zhangsan’,18)
p2 = Person(‘zhangsan’,18)
print(‘0x%X’ % id(p1))
print(‘0x%X’ % id(p2))
print(‘p1 is p2’,p1 is p2)
print(‘p1 == p2’,p1==p2)
运行后的结果为:
这时的 other 等于对应的是 p2 内存地址,会把 p2 传给 other。p1 ==p2 的值变成了 none,因为 p1 == p2 本质是对对象的调用 p1.__eq__(p2),获取这个方法的返回结果。
修改语句,使得姓名和年龄相等返回 True,否则是 False
def __eq__(self,other):
if self.name == other.name and self.age ==other.age:
return True
return False
if 对应得 else 可以不写,self 是指哪一个调用了__eq__,就是哪一个。
还可以继续简写为以下形式:
def __eq__(self,other):
return self.name == other.name and self.age ==other.age
代码内容:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __eq__(self,other):
return self.name == other.name and self.age ==other.age
p1 = Person(‘zhangsan’,18)
p2 = Person(‘zhangsan’,18)
print(‘0x%X’ % id(p1))
print(‘0x%X’ % id(p2))
print(‘p1 is p2’,p1 is p2)
print(‘p1 == p2’,p1==p2)
运行后的结果为:
再加入对象p3,p3 = Person(‘zhangsan’,19)
并加入输出语句print(p1 == p3)
代码内容:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __eq__(self,other):
return self.name == other.name and self.age ==other.age
p1 = Person(‘zhangsan’,18)
p2 = Person(‘zhangsan’,18)
p3 = Person(‘zhangsan’,19)
print(‘0x%X’ % id(p1))
print(‘0x%X’ % id(p2))
print(‘p1 is p2’,p1 is p2)
print(‘p1 == p2’,p1==p2)
print(p1 == p3)
运行后的结果为:
总之,== 得本质就是调用__eq__方法,初次之外还有更多得魔法方法可以学习。