python3 未定义 __ne__ returns 与定义相同的值 __eq__
python3 undefined __ne__ returns same value as defined __eq__
我有一个 class MyClass,其中 __eq__
定义如下:
def __eq__(self, other):
try:
other = MyClass(other)
except Exception as e:
raise ValueError(f"MyClass.__eq__ failed: {other} doesn't appear to be a valid MyClass type. \n", e )
prefix_i1 = re.findall("[ab]" , self )
prefix_i2 = re.findall("[ab]" , other )
if len( set( prefix_i1 + prefix_i2 ) ) > 1:
return False # ie: "a07" != "b07" BUT "k07" == "b07"
else:
return self.num_string == other.num_string # eg: "i3" == "i03"
哪里
self.num_string = "".join(filter(str.isdigit, self )).zfill(2)
没想到,我得到了这个结果:
> MyClass('b05') == MyClass('i05')
True
> MyClass('b05') != MyClass('i05')
True
我认为 __ne__
默认是 not __eq__
并且不鼓励明确定义它,因为 Python 3.
我做错了什么?
这是一个最小的可重现示例:
import re
class MyClass(str):
def __new__(cls, *args, **kwargs):
if args[0] is None:
return str.__new__(cls, '' )
if not ( isinstance(args[0], int) or
( isinstance(args[0], str) and re.match("[iab]?[0-9]{1,2}", args[0].lower()) ) ):
raise ValueError("MyClass failed because the provided input '{}' is not valid... .".format(args[0]))
lower_str_input = str(args[0]).lower()
return str.__new__(cls, lower_str_input )
def __init__(self, input_string=''):
self.num_string = "".join(filter(str.isdigit, self )).zfill(2)
def __eq__(self, other):
try:
other = MyClass(other)
except Exception as e:
raise ValueError("MyClass.__eq__ failed" )
prefix_i1 = re.findall("[ab]" , self )
prefix_i2 = re.findall("[ab]" , other )
if len( set( prefix_i1 + prefix_i2 ) ) > 1:
return False # ie: "a07" != "b07" BUT "k07" == "b07"
else:
return self.num_string == other.num_string # eg: "i3" == "i03"
MyClass('b05') == MyClass('i05')
MyClass('b05') != MyClass('i05')
I thought __ne__
was by default not __eq__
and defining it explicitly was discouraged since Python 3.
为了你自己的 类,是的。默认情况下,它们将派生自 object
,后者实现了该逻辑。
然而,built-ins(以及由此派生的所有内容)可能有点奇怪。
这是一个更简单的例子:
... class x(str):
... def __eq__(self, other):
... print('eq called')
... return str.__eq__(self, other)
...
>>> x('foo') != 'foo'
False
答案正确,但未调用 __eq__
(因此没有打印消息)。这个答案来自str.__ne__
,它(显然)是单独实现的(不是__eq__
)。
我有一个 class MyClass,其中 __eq__
定义如下:
def __eq__(self, other):
try:
other = MyClass(other)
except Exception as e:
raise ValueError(f"MyClass.__eq__ failed: {other} doesn't appear to be a valid MyClass type. \n", e )
prefix_i1 = re.findall("[ab]" , self )
prefix_i2 = re.findall("[ab]" , other )
if len( set( prefix_i1 + prefix_i2 ) ) > 1:
return False # ie: "a07" != "b07" BUT "k07" == "b07"
else:
return self.num_string == other.num_string # eg: "i3" == "i03"
哪里
self.num_string = "".join(filter(str.isdigit, self )).zfill(2)
没想到,我得到了这个结果:
> MyClass('b05') == MyClass('i05')
True
> MyClass('b05') != MyClass('i05')
True
我认为 __ne__
默认是 not __eq__
并且不鼓励明确定义它,因为 Python 3.
我做错了什么?
这是一个最小的可重现示例:
import re
class MyClass(str):
def __new__(cls, *args, **kwargs):
if args[0] is None:
return str.__new__(cls, '' )
if not ( isinstance(args[0], int) or
( isinstance(args[0], str) and re.match("[iab]?[0-9]{1,2}", args[0].lower()) ) ):
raise ValueError("MyClass failed because the provided input '{}' is not valid... .".format(args[0]))
lower_str_input = str(args[0]).lower()
return str.__new__(cls, lower_str_input )
def __init__(self, input_string=''):
self.num_string = "".join(filter(str.isdigit, self )).zfill(2)
def __eq__(self, other):
try:
other = MyClass(other)
except Exception as e:
raise ValueError("MyClass.__eq__ failed" )
prefix_i1 = re.findall("[ab]" , self )
prefix_i2 = re.findall("[ab]" , other )
if len( set( prefix_i1 + prefix_i2 ) ) > 1:
return False # ie: "a07" != "b07" BUT "k07" == "b07"
else:
return self.num_string == other.num_string # eg: "i3" == "i03"
MyClass('b05') == MyClass('i05')
MyClass('b05') != MyClass('i05')
I thought
__ne__
was by defaultnot __eq__
and defining it explicitly was discouraged since Python 3.
为了你自己的 类,是的。默认情况下,它们将派生自 object
,后者实现了该逻辑。
然而,built-ins(以及由此派生的所有内容)可能有点奇怪。
这是一个更简单的例子:
... class x(str):
... def __eq__(self, other):
... print('eq called')
... return str.__eq__(self, other)
...
>>> x('foo') != 'foo'
False
答案正确,但未调用 __eq__
(因此没有打印消息)。这个答案来自str.__ne__
,它(显然)是单独实现的(不是__eq__
)。