Python在初始化时重新排序类属性列表

时间:2017-01-31 09:59:47

标签: python python-3.x

您好我有一个列表作为属性。当我实现这个类时,我想为这个实例重新排序这个列表。例如:

class A(object):

    my_list = [1,2,3,4,5]

    def __init__(self, first):
        self.reorder_list(first)

    def reorder_list(self, first):
        self.my_list.insert(
             0,
             self.my_list.pop(
                  self.my_list.index(first)
             )
        )

这应该做到以下几点:

a = A(3)
a.my_list
[Out]: 3,1,2,4,5

b = A(4)
b.my_list
[Out]: 4,1,2,3,5

这似乎有效....但并不总是......因为结果不一致。当我这样做时:

def __init__(self, first):
    self.my_list = self.reorder_list(first)

def reorder_list(self, first):
    my_copy = copy.copy(self.my_list)
    ... do reordering on my_copy ...
    return my_copy 

然后它一直工作。

有人可以向我解释为什么我的第一段代码不是这样做的,如果我的第二种方式(使用副本然后重新生成self.my_list)是正确的方法吗?< / p>

3 个答案:

答案 0 :(得分:1)

在Python中为类属性赋值时,该值将在该类的所有实例之间共享。出于这个原因,当您在insert的任何实例中self.my_listA时,它会反映在A的所有实例中 - 它们都共享相同的列表。

要创建实例属性,您应设置self.some_attribute,而不是在类范围中设置some_attribute。在第二个示例中,您将self.my_list重新分配给__init__中的新列表对象,因此my_list不再引用类范围属性。它特定于该实例。

您的解决方案是正确的。为了避免混淆,最好不要为类和实例属性使用相同的名称。例如:

class A(object):

    default_list = [1, 2, 3, 4, 5]

    def __init__(self, first):
        self.my_list = self.reorder_list(first)

    def reorder_list(self, first):
        my_copy = copy.copy(self.default_list)
        # ... do reordering on my_copy ...
        return my_copy 

答案 1 :(得分:1)

这是由于班级中my_list的范围。根据定义,my_list是类级别属性。因此,可以在第一次实例化后通过A.my_list或a.my_list访问它。因此,初始重新排序的副作用A.my_list已更改为最后一个实例化设置的内容。该副本有效,因为创建了一个新列表,并使用类级别属性中的值进行初始化,而是使用它。

>>> A.my_list
[1, 2, 3, 4, 5]
>>> a = A(4)
>>> a.my_list
[4, 2, 1, 5, 3]
>>> A.my_list
[4, 2, 1, 5, 3]

答案 2 :(得分:0)

为了让它像你想象的那样工作,你也可以这样做:

class A(object):

my_list = []

def __init__(self, first):
    self.my_list = [1, 2, 3, 4, 5]
    self.reorder_list(first)

def reorder_list(self, first):

    self.my_list.insert(
         0,
         self.my_list.pop(
              self.my_list.index(first)
         )
    )