您好我有一个列表作为属性。当我实现这个类时,我想为这个实例重新排序这个列表。例如:
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>
答案 0 :(得分:1)
在Python中为类属性赋值时,该值将在该类的所有实例之间共享。出于这个原因,当您在insert
的任何实例中self.my_list
项A
时,它会反映在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)
)
)