我声明了MyClass
的三个实例。我想将每个实例存储在列表变量instances
中。在instance
附加到instances
之前,我仔细检查它是否已经在列表中。有趣的是,所有三个实例看起来与Python完全相同。为什么会发生这种情况,以及我们应该知道什么以避免将来出现这样的意外?
instances=[]
for i in range(3):
instance=MyClass(i)
for each in instances:
if each==instance:
print 'THE SAME?', each.ID,'==', instance.ID
if instance not in instances:
print "Instance %s is not in instances"%instance.ID
instances.append(instance)
else:
print "Instance %s is already in instances"%instance.ID
index=instances.index(instance)
instanceFromList=instances[index]
print "COMPARE: instance.ID:", instance.ID, ' instanceFromList.ID:', instanceFromList.ID
print 'Number of instances stored:', len(instances)
输出:
Instance 0 is not in instances
THE SAME? 0 == 1
Instance 1 is already in instances
COMPARE: instance.ID: 1 instanceFromList.ID: 0
THE SAME? 0 == 2
Instance 2 is already in instances
COMPARE: instance.ID: 2 instanceFromList.ID: 0
Number of instances stored: 1
答案 0 :(得分:2)
因为列表是空的,所以它们相等。这是因为用于确定每个实例是否在“实例”列表中的比较是值comarison ,而不是身份比较。
如果在将ID = 1添加到MyClass实例之前将其添加到“实例”列表中,那么您的代码将添加ID = 2的空MyClass实例。
不使用列表子类型的示例:
>>> a = list()
>>> b = list()
>>> a == b # equal value
True
>>> a is b
False # different identity
>>> c = list()
>>> c.append(a)
>>> a in c
True
>>> b in c
True
>>> a.append("a value")
>>> a == b # now the values differ
False
>>> a in c # The value of 'a' changed, and 'a' is still in 'c'
True
>>> b in c # 'b' is still empty, and there's no empty list in 'c'
False
为了支持基于ID实例变量的“MyClass in list”比较,您必须在类中实现__eq__
和__ne__
比较方法。然后,这些方法应比较实例的类型及其ID。
请注意,如果实现此功能,您也将无法比较MyClass实例的内容。
答案 1 :(得分:1)
我不确定为什么你的行为与常规列表不同:
instances = []
for i in range(3):
instance = []
if instance not in instances:
print 'Adding instance to list...'
instances.append(instance)
else:
print 'Instance is already present in list'
print instances
print 'Number of instances stored:', len(instances)
打印:
Adding instance to list...
Instance is already present in list
[[]]
Instance is already present in list
[[]]
Number of instances stored: 1
如果您希望它通过考虑您提供的ID来某种程度地区分您的list
子类,则您必须自己overriding how your object responds to equality tests定义该行为。