python中对象相等判断(is、==与__dict__的使用)

一、对象的要素

python中对象包含三个基本要素,分别是:

  • id(身份标识) 可以理解为c里面的指针或内存位置
  • type(数据类型)
  • value(值)

类型:python的基本对象有Number、String、List、Tuple、Set、Dictionary六种,当然还有对象的实例化,他们的类型就是对象的类名。可以通过type(对象)来获取

>>>a1=1
>>>a2=1
>>>print(id(a1))
140611277590096

>>>print(id(a2))
140611277590096

>>> a='op'
>>> b='op'
>>> print(id(a))
1694624136416
>>> print(id(b))
1694624136416
>>>

>>>a1=[1,2]
>>>a2=[1,2]
>>>print(id(a1))
4477835456

>>>print(id(a2))
4477833512


>>>print(id(a2))
4477833512

>>> class test:
...     def __init__(self,s):
...             self.s=s
...
>>> t1=test("hello")
>>> t2=test("helo")
>>> print(id(t1))
4511016936
>>> print(id(t2))
4511017008

可以看出,number和string在赋值时,对于同一值不重新分配内存,所以同一个值id相同。
而其他数据类型(包括自定义类)在每次赋值时都会为每一个对象开辟一个新内存予以存储,所以id不同。

二、==与is的使用

class test:
     def __init__(self,s):
             self.s=s
a1=1
a2=1
print(a1==a1)   #True
print(a1 is a2) #True


a1=[1,2]
a2=[1,2]
print(a1==a2)   #True
print(a1 is a2) #False


t1=test("hello")
t2=test("hello")
print(t1==t2)   #False

  • ==用于判断数值是否相等,因此对于六大基本数据类型而言,相同的值即可判定相等。而对于其他类的实例化对象而言,存储和比较的可以认为是内存地址或者id,因此此时即使拥有相同属性也会因为id不同而被判定为不相等。
  • is,这是用于直接比较二者的地址是否相同

三、__dict__的使用

我们知道java中可以通过重写类equals的方法实现类对象的属性相等判断,可是python中并没有这样的函数,除了自定义equals函数有没有其他方便的实现方式呢?

利用python中的属性dict可以实现

class test:
    clsvar=1
    def __init__(self,invar):
        self.invar=invar
print(test.__dict__)
输出:{'clsvar': 1, '__module__': '__main__', '__doc__': None, '__init__': <function __init__ at 0x100aecf50>}

t1=test(1)
t2=test(1)
print(t1.__dict__)
输出:{'invar': 1}

print(t1==t2)
输出:False

print(t1.__dict__==t2.__dict__)
输出:True

其中clsvar称之为类变量,invar称之为实例变量
python中__dict__是一个字典,键是属性名,值为属性值。
Python的实例有自己的dict,它对应的类也有自己的dict (但是有些特殊的对象是没有dict属性的,这里不做讨论)

当打印类的dict属性时,列出了类所包含的属性,包括一些类内置属性和类变量clsvar以及构造方法init

而实例变量则包含在实例对象t1的dict属性中,利用这一点可以很容易实现比较t1和t2的实例变量是否相同。
一个对象的属性查找顺序遵循首先查找实例对象自己,然后是类,接着是类的父类。

#实例先检查对象自身
t1.clsvar=10
print(test.clsvar)
输出:1

print(t1.clsvar)
输出:10

#没类对象先检查类自身
test.clsvar=20
print(test.clsvar)
输出:20

print(t1.clsvar)
输出:10

print(t2.clsvar)
输出:

#给类和实例中未定义的变量赋值
test.m=5
t1.x=5
print(test.m)
print(t1.x)
输出:55

t3=test(1)
print(t3.m)
输出:5

print(t3.x)
报错:AttributeError: test instance has no attribute 'x'

一个将字典转换成对象的小技巧,如果我们有一个字典如下:

dict={"a":1,
     "b":2,
     "c":3}

现在想将其转换为一个对象,通常会这样写:

class test:
    def __init__(self,dict):
        self.a=dict['a']
        self.b=dict['b']
        self.c=dict['c']

但是在了解了dict属性之后可以这样写:

class test:
    def __init__(self,dict):
        self.__dict__.update(dict)

我目前用的最多的就是python对象的比较,即比较两个python对象是否相等,看个例子:

class student(object):
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def __eq__(self, *args, **kwargs):
        return object.__eq__(self, *args, **kwargs)

like = student("like",25,"male")
xue = student("xue",23,"female")
dong = student("like",25,"male")

print(like is xue) #False
print(like is dong) #False
print(like == dong) #False

这里有两个student类的实例化对象,like和xue很明显是两个不同的对象,他们的不同体现在所占内存地址不同且对象的属性也不同。

like和dong虽然属性相同,但是is和==两种判断的结果也都为false,在实际情况中,我们大多都希望like和dong属性相同,就认为是同一个对象,所以我们需要重写类的eq方法:

class student(object):
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def __eq__(self,other):
        return self.__dict__ == other.__dict__
print(like == dong) #True    

调用一个对象的dict方法可以用字典的形式输出其属性列表,由于两个对象的属性相同,所以==运算为True。

自定义python对象相等的条件

当然在实际情况下,可以更灵活的定义两个对象相等的条件,比如名字一样就认为相等。

class student(object):
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def __eq__(self,other):
        return self.name == other.name

like = student("like",25,"male")
dong = student("like",23,"female")        

print(like == dong) #True  
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值