📜  Python中“__eq__”与“is”与“==”的区别

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

Python中“__eq__”与“is”与“==”的区别

有多种方法可以比较Python中任何类型的对象。 Python具有“ == ”运算符、“ is ”运算符和“ __eq__ ”dunder 方法,用于比较一个类的两个对象或自定义比较。本文解释了上述三个运算符以及它们之间的区别。

==运算符

“==”运算符比较两个对象的值或相等性,而Python的“is”运算符检查两个变量是否指向内存中的同一个对象。

示例 1:

Python3
# lists initialization
x = [1, 2]
y = [1, 2]
  
z = y
  
# comparisons
print("x == y : ", x == y)
print("z == y : ", z == y)
  
# location in memory
print("Location of x is ", id(x))
print("Location of y is ", id(y))
print("Location of z is ", id(z))


Python3
class Student:
    def __init__(self, name):
        self.name = name
  
  
divyansh = Student("Divyansh")
shivansh = Student("Divyansh")
  
print("divyansh == shivansh : ", (divyansh == shivansh))


Python3
class Student:
    def __init__(self, name):
        self.name = name
  
    def __eq__(self, other):
        if isinstance(other, Student):
            if other.name == self.name:
                return True
        return False
  
  
divyansh = Student("Divyansh")
shivansh = Student("Divyansh")
  
print("divyansh == shivansh : ", (divyansh == shivansh))


Python3
class Student:
    def __init__(self, name):
        self.name = name
  
    def __eq__(self, other):
        if isinstance(other, Student):
            if other.name == self.name:
                return True
        return False
  
  
divyansh = Student("Divyansh")
shivansh = Student("Divyansh")
  
print("divyansh is shivansh : ", (divyansh is shivansh))


Python3
class Student:
    def __init__(self, name):
        self.name = name
  
    def __eq__(self, other):
        if isinstance(other, Student):
            if other.name == self.name:
                return True
        return False
  
  
divyansh = Student("Divyansh")
shivansh = divyansh
  
print("divyansh is shivansh : ", (divyansh is shivansh))


Python3
x = [1, 2]
y = [1, 2]
z = y
print("x is y : ", x is y)
print("z is y : ", z is y)
print("Location of x is ", id(x))
print("Location of y is ", id(y))
print("Location of z is ", id(z))


输出
x == y :  True
z == y :  True
Location of x is  140169895643144
Location of y is  140169895642952
Location of z is  140169895642952

示例 2:

蟒蛇3

class Student:
    def __init__(self, name):
        self.name = name
  
  
divyansh = Student("Divyansh")
shivansh = Student("Divyansh")
  
print("divyansh == shivansh : ", (divyansh == shivansh))
输出
divyansh == shivansh :  False

在上面的例子中,我们应该得到一个输出True ,但我们收到的输出是False 。这是因为,对于用户定义类的对象,我们需要指定我们将如何比较它们。我们创建的Student对象不知道两个学生相等的标准是什么,也许他们有相同的属性“名称”,也许他们有一堆关于他们的其他特征。什么需要相同才能让我们说一个 Student 对象与另一个 Student 相同。好吧,这就是我们将通过实现一个名为__eq__的方法自己指定的内容。这是dunder方法之一 在Python中。它允许我们覆盖Python中“ == ”运算符的基本功能。

示例 3:

蟒蛇3

class Student:
    def __init__(self, name):
        self.name = name
  
    def __eq__(self, other):
        if isinstance(other, Student):
            if other.name == self.name:
                return True
        return False
  
  
divyansh = Student("Divyansh")
shivansh = Student("Divyansh")
  
print("divyansh == shivansh : ", (divyansh == shivansh))
输出
divyansh == shivansh :  True

实现这个 dunder 方法,在 Student 类的两个对象之间使用“ == ”运算符并获得准确的值比较,现在如果我将其切换为 ' is '运算符,情况将会有所不同。

示例 4:

蟒蛇3

class Student:
    def __init__(self, name):
        self.name = name
  
    def __eq__(self, other):
        if isinstance(other, Student):
            if other.name == self.name:
                return True
        return False
  
  
divyansh = Student("Divyansh")
shivansh = Student("Divyansh")
  
print("divyansh is shivansh : ", (divyansh is shivansh))
输出
divyansh is shivansh :  False

在上面的代码片段中,我们收到False作为输出,这是因为divyansh将与shivansh不同,尽管这些对象具有相同的值。然而,它们具有不同的存储位置,即它们是不同且独特的对象,可以在任何时间点独立地改变它们的属性。

示例 5:

蟒蛇3

class Student:
    def __init__(self, name):
        self.name = name
  
    def __eq__(self, other):
        if isinstance(other, Student):
            if other.name == self.name:
                return True
        return False
  
  
divyansh = Student("Divyansh")
shivansh = divyansh
  
print("divyansh is shivansh : ", (divyansh is shivansh))
输出
divyansh is shivansh :  True

现在在上面的示例中,输出为True,这是因为 shivansh 指向与 divyansh 指向的同一 Student 对象。

“是”运算符

“is”运算符比较两个对象的身份。这里我们比较对象本身。

示例 6:

蟒蛇3

x = [1, 2]
y = [1, 2]
z = y
print("x is y : ", x is y)
print("z is y : ", z is y)
print("Location of x is ", id(x))
print("Location of y is ", id(y))
print("Location of z is ", id(z))
输出
x is y :  False
z is y :  True
Location of x is  139987316430856
Location of y is  139987316430664
Location of z is  139987316430664

在上面的示例中,即使 x 和 y 具有相同的值,它们也会将它们存储在内存中的不同位置。所以很明显,即使对象在值方面相同,它们在内存中的位置实际上是不同的。我们还看到在上面的片段中z is y给出True ,这是因为这些对象实际上是相同的,即上面 y 的位置和 z 的位置完全相同。