【问题标题】:Equality and identity - python [duplicate]平等和身份 - python [重复]
【发布时间】:2015-08-10 10:57:59
【问题描述】:

对于下面定义的用户定义的pythonclassa == bFalse

>>> class Account():
        def __init__(self, account_holder):
            self.balance = 0
            self.holder = account_holder

>>> a = Account('Jim')
>>> b = Account('Jim')
>>> a is b
False
>>> a == b
False

但在以下情况下,相等(==)运算符显示True

>>> lst1 = [1, 2]
>>> lst2 = [1, 2]
>>> lst1 == lst2
True            # this is true
>>> lst1 is lst2
False
>>> str1 = 'abc'
>>> str2 = 'abc'
>>> str1 == str2
True            # this is true
>>> str1 is str2
True
>>> tup1 = (1, 2)
>>> tup2 = (1, 2)
>>> tup1 == tup2
True             # this is true
>>> tup1 is tup2
False
  1. 当用户定义的类在 python 中定义时,我如何理解相等运算符 (==) 的工作原理?

  2. class object 的哪个方法为 python 中任何用户定义类的所有实例提供标识?

【问题讨论】:

  • 我不认为这是身份主题的重复问题

标签: python python-3.x


【解决方案1】:

你必须自己实现类相等,方法是在你的类中重写 __eq__ 方法。更多详情请看这里:__eq__

在你的特殊情况下,是这样的:

class Account():
  def __init__(self, account_holder):
    self.balance = 0
    self.holder = account_holder

  def __eq__(self, other):
     return self.holder == other.holder

  def __ne__(self, other):
     return not self.__eq__(other)

现在a == b 应该返回 True。

如果您想要更多示例,How to override comparison operators 提供了很好的示例。

编辑:正如@SergeBallesta 在 cmets 中所提到的,并且也正如文档所敦促的那样,覆盖 __eq__() 方法的反射是一个好主意,即 __ne__()。

【讨论】:

  • 对于身份,我需要覆盖什么?
  • 您不能覆盖身份。这没有任何意义。两个对象要么是同一个对象,要么不是。假装两个不同的对象是相同的会很疯狂。
  • @kindall 首先object.__hash__() 实际上返回用户定义类的所有实例的标识,对吗?如果是,那么object.__hash__() 的返回类型/类型大小位是多少?在 java 中,必须覆盖标识,因为 public int hashCode() 返回 32 位整数,尽管我创建了超过 2^32 个对象。
  • @overexchange __hash__() 返回一个整数。这只是一个设计选择,除非重写 __hash__() 函数,否则默认使用从 id(obj) 派生的结果,而 Cpython 中的 id(obj) 是对象的地址。另一方面,“is”运算符测试它是否在内存中的位置完全相同,简单地说。检查这个很好地解释了这一点的 SO 问题:stackoverflow.com/questions/132988/…
  • Python 中的整数可以是任意位数。无论如何,两个不同的对象拥有相同的哈希是完全合法的。
【解决方案2】:

覆盖 __eq____ne__ 方法。

class Account():
    def __init__(self, account_holder):
        self.balance = 0
        self.holder = account_holder
    def __eq__(self, other):
        """Override the default equals"""
        return (isinstance(other, self.__class__)
            and self.__dict__ == other.__dict__)
    def __ne__(self, other):
        """non-equality"""
        return not self.__eq__(other)

a = Account('Jim')
b = Account('Jim')

print a == b

c = Account('Not Jim')
print a == c

输出:

True
False

关于身份is 运算符。如果ab 都持有对同一对象的引用,则a is b 将是True

a = b
print a is b # return True
print a is c # return False

你可以阅读类似的功能here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-29
    • 2012-01-19
    • 2023-03-21
    • 2020-10-31
    • 2013-11-03
    • 2011-07-23
    • 2021-04-14
    相关资源
    最近更新 更多