当Class继承自内置List时

时间:2015-08-20 21:21:58

标签: python list class inheritance

我声明了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

2 个答案:

答案 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定义该行为。