Noe*_*ans 17 python duck-typing equality
你有一个需要等于测试的Python类.Python应该使用duck-typing,但在eq函数中包含或排除isinstance测试是否更好/更准确?例如:
class Trout(object):
def __init__(self, value):
self.value = value
def __eq__(self, other):
return isinstance(other, Trout) and self.value == other.value
Run Code Online (Sandbox Code Playgroud)
amc*_*abb 14
在__eq__方法中使用isinstance 很常见.原因是如果__eq__方法失败,它可以__eq__从另一个对象回退一个方法.大多数常规方法都是显式调用的,但是它们__eq__是隐式调用的,所以它需要更频繁地查找先发制人.
编辑(感谢提醒,Sven Marnach):
要使其回退,您可以返回NotImplemented单例,如下例所示:
class Trout(object):
def __init__(self, value):
self.value = value
def __eq__(self, other):
if isinstance(other, Trout):
return self.value == other.value
else:
return NotImplemented
Run Code Online (Sandbox Code Playgroud)
假设a RainbowTrout知道如何将自己与a Trout或另一个进行比较RainbowTrout,但Trout只知道如何将自身与a进行比较Trout.在这个例子中,如果你测试mytrout == myrainbowtrout,Python将首先调用mytrout.__eq__(myrainbowtrout),注意它失败,然后调用myrainbowtrout.__eq__(mytrout),这成功.
使用isintsance()方法通常很好__eq__().但是,False如果isinstance()检查失败,则不应立即返回- 最好返回NotImplemented以给予other.__eq__() 执行机会:
def __eq__(self, other):
if isinstance(other, Trout):
return self.x == other.x
return NotImplemented
Run Code Online (Sandbox Code Playgroud)
这将在多个类定义的类层次结构中变得特别重要__eq__():
class A(object):
def __init__(self, x):
self.x = x
def __eq__(self, other):
if isinstance(other, A):
return self.x == other.x
return NotImplemented
class B(A):
def __init__(self, x, y):
A.__init__(self, x)
self.y = y
def __eq__(self, other):
if isinstance(other, B):
return self.x, self.y == other.x, other.y
return NotImplemented
Run Code Online (Sandbox Code Playgroud)
如果您False立即返回,就像在原始代码中那样,您将失去A(3) == B(3, 4)和之间的对称性B(3, 4) == A(3).
“鸭子类型”原则是,你不在乎它是什么other,只要它有一个value属性即可。因此,除非您的属性共享具有冲突语义的名称,否则我建议这样做:
def __eq__(self, other):
try:
return self.value == other.value
except AttributeError:
return False # or whatever
Run Code Online (Sandbox Code Playgroud)
(或者你可以测试是否other有一个value属性,但是“请求宽恕比获得许可更容易”)
| 归档时间: |
|
| 查看次数: |
2151 次 |
| 最近记录: |