gpt4 book ai didi

python-3.x - 子类和父类的比较

转载 作者:行者123 更新时间:2023-12-05 06:49:39 24 4
gpt4 key购买 nike

问题

在两个类之间实现比较方法时,结果不符合预期。

class A:
def __init__(self, name: str) -> None:
self.name = name

def __eq__(self, other: object) -> bool:
if not isinstance(other, A):
return NotImplemented
return self.name == other.name

class B(A):
def __init__(self, name: str, value: int) -> None:
super().__init__(name)
self.value = value

def __eq__(self, other: object) -> bool:
if not isinstance(other, B):
return NotImplemented
return self.name == other.name and self.value == other.value

a = A("a")
b = B("a", 1)

print(a == b) # True
print(b == a) # True

我想要的是这些具有不同属性的类的不同实例不相等,所以我希望在这两种情况下都为 False

我们得到 True 的原因是因为我们在 B__eq__ 方法中返回 NotImplemented 如果另一个对象不是 B 的实例。这会导致调用 A__eq__ 方法。由于 BA 的子类,isinstance(b, A) 返回 True。

解决方案(尝试 1)

我们可以使用 type(other) is A 而不是使用 isinstance(other, A) 进行检查:

class A:
def __init__(self, name: str) -> None:
self.name = name

def __eq__(self, other: object) -> bool:
if not type(other) is A:
return NotImplemented
return self.name == other.name

class B(A):
def __init__(self, name: str, value: int) -> None:
super().__init__(name)
self.value = value

def __eq__(self, other: object) -> bool:
if not type(other) is B:
return NotImplemented
return self.name == other.name and self.value == other.value

a = A("a")
b = B("a", 1)

print(a == b) # False
print(b == a) # False

这按预期工作,但是 mypy 不喜欢它:

error: Returning Any from function declared to return "bool"  [no-any-return]
error: "object" has no attribute "name" [attr-defined]
error: Returning Any from function declared to return "bool" [no-any-return]
error: "object" has no attribute "name" [attr-defined]
error: "object" has no attribute "value" [attr-defined]

解决方案(尝试 2)

据我所知,为了让 mypy 喜欢这个解决方案,必须保留 isinstance 检查。所以我在值比较中加入了类型检查。

class A:
def __init__(self, name: str) -> None:
self.name = name

def __eq__(self, other: object) -> bool:
if not isinstance(other, A):
return NotImplemented
return self.name == other.name and type(other) is A

class B(A):
def __init__(self, name: str, value: int) -> None:
super().__init__(name)
self.value = value

def __eq__(self, other: object) -> bool:
if not isinstance(other, B):
return NotImplemented
return self.name == other.name and self.value == other.value and type(other) is B

a = A("a")
b = B("a", 1)

print(a == b) # False
print(b == a) # False

现在 mypy 可以处理代码了,但是 pylint 仍然不喜欢这个解决方案:

C0123: Using type() instead of isinstance() for a typecheck. (unidiomatic-typecheck)

如何正确解决这个问题?

最佳答案

你非常接近!

检查两个对象是否使用同一个类的标准过程是这样的:

if type(x) == type(y):

但是,很多 linter 会提示并要求您使用 isinstance,因为他们认为您也希望它对子类的计算结果为真。您能做的最好就是忽略它们。

希望这能解决您的问题!

编辑:您应该能够使用 is 而不是 ==

关于python-3.x - 子类和父类的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66570204/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com