python集合包含与列表包含
我正在使用python 2.7 考虑以下代码片段(示例是人为设计的): 此操作的输出出乎意料(至少对我而言): 在第一种情况下,给定的日期在python集合包含与列表包含,python,list,set,contains,equality,Python,List,Set,Contains,Equality,我正在使用python 2.7 考虑以下代码片段(示例是人为设计的): 此操作的输出出乎意料(至少对我而言): 在第一种情况下,给定的日期在计划集中找到,因为我已经覆盖了\uuuuuu散列和\uuuuu eq函数 根据我的理解,中的操作符将检查集合的哈希和相等性,但对于列表,它将简单地迭代列表中的项目并检查相等性 那么这里发生了什么?为什么我对列表中的中的进行的第二次测试失败 我是否必须覆盖列表的其他函数?问题是比较调用的是一个与您要查找的相反的\uuuuu eq\uuuu函数。当您有一个Sch
计划集
中找到,因为我已经覆盖了\uuuuuu散列
和\uuuuu eq
函数
根据我的理解,中的操作符将检查集合的哈希和相等性,但对于列表,它将简单地迭代列表中的项目并检查相等性
那么这里发生了什么?为什么我对列表中的中的进行的第二次测试失败
我是否必须覆盖列表的其他函数?问题是比较调用的是一个与您要查找的相反的\uuuuu eq\uuuu
函数。当您有一个ScheduleData()==datetime.date()
但是中的操作符正在以相反的顺序执行比较,datetime.date()==ScheduleData()
而它没有调用您定义的时,定义的方法可以工作。只有充当左侧的类才会调用其\uuuu eq\uu
这个问题出现在Python2而不是Python3中的原因与std库中的datetime.date.\uuu eq\uu
的定义有关。以以下两类为例:
class A(object):
def __eq__(self, other):
print ('A.__eq__')
return False
class B(object):
def __eq__(self, other):
print ('B.__eq__')
items = [A()]
B() in items
运行此代码将在Python2和Python3下打印B.\uuuu eq\uuuu
。B
对象用作lhs,就像Python 2中使用的datetime.date
对象一样。但是,如果我重新定义B.\uuuuueq\uuuu
类似于Python 3对datetime.date.\uuuuueq\uuu
的定义:
class B(object):
def __eq__(self, other):
print ('First B.__eq__')
if isinstance(self, other.__class__):
print ('B.__eq__')
return NotImplemented
然后:
在Python 2和Python 3下打印。返回NotImplemented
会导致参数反转的检查
在你的类中使用timetuple
可以解决这个问题,正如@TimPeters所说的(有趣的怪癖我不知道),尽管它似乎不需要是一个函数
class ScheduleData:
timetuple = None
除了你已经拥有的,你还需要什么。@RyanHaining是正确的。要获得真正奇怪的解决方法,请将此方法添加到类中:
def timetuple(self):
return None
然后您的程序将打印两次True
。这其中有很多原因,与Python2中比较过于宽松的不幸历史有关。timetuple()
解决方案主要在本部分文档中解释:
注意,以防止比较回落到
比较对象地址、日期和时间的默认方案
如果另一个比较对象
也不是datetime对象。然而,没有实现
如果另一个比较符有timetuple()则返回
属性这个钩子为其他类型的日期对象提供了一个
实现混合类型比较的机会。如果没有,,
将datetime对象与
如果类型不同,则会引发TypeError,除非进行比较
是==或!=。后一种情况返回假或真,
分别
datetime
是Python中添加的首批类型之一,它试图提供不那么令人惊讶的比较行为。但是,在Python 3为我工作之前,它不能变得“真正干净”。。Python3.3我想知道为什么。已确认,它在Python 2.7上不起作用。请尝试添加\uu neq\uuuuu
。@tcaswell,谢谢,我已经尝试过了,并且应该提到它,但它不起作用-那些\uuuu neq\uuuuu
和\uuuu eq\uuu
函数在第二种情况下似乎没有被调用。比较datetime.date(2010,8)==时间表列表[1]
至时间表列表[1]==日期时间.日期(2010,8,8)
。您是否得到False
,然后得到True
?False。我认为问题在于类。我要补充的是,这种情况下的行为取决于使用datetime.date
作为比较类型。例如,如果传入一个int或string作为“date”值,则同一个类可以正常工作。所以问题还在于datetime.date
与内置类型没有相同的自动双面比较行为。@BrenBarn我也怀疑这一点我现在正在查看库代码谢谢tim,我接受了ryan的答案,但你的答案同样有用。
First B.__eq__
A.__eq__
class ScheduleData:
timetuple = None
def timetuple(self):
return None