将类的实例追加到列表会覆盖以前的实例属性



所以我试图使用嵌套while循环生成一个类对象列表。我有两种类型的类,normal_class和special_class。

对于special_class,我通过做special_cclass.set(x,y(来给它x,y坐标。对于普通类,我就保持原样。

如果我通过执行special_class.set(x,y(来附加另一个special_cclass,然后ls.append(special_cClass(,它会覆盖第一个的坐标,所以我最终得到两个具有相同坐标的special_class,而不是两个具有不同坐标的specical_class。

我最近才开始用Python编程,所以任何帮助都会很有帮助:(

这是一些伪代码:

  1. 输入是一个字符串,即"XXY">
  2. 我将这些字符中的每一个与我创建的字典进行比较,即dict={"X":special_class((,"Y":normal_class}
  3. 我想设置special_class的坐标,normal_class没有坐标属性
  4. 如果字典中的character_from_string==键,请检查它是特殊类还是普通类。然后使用值对
  5. 如果它是一个特殊的类,则对一些数字x,y设置_pos(x,y(。如果正常,通过
  6. 将类实例附加到列表中
  7. 所以我希望有一个输出,比如[special_classobject,special_class object,normal_class object]
  8. 如果我执行ls[0].get_pos和ls[1].get_pos,即使我将其设置为不同的x,y,它也会返回相同的值。为什么?我该怎么解决这个问题

代码!


class special_class:
def __init__(self):
self.char = "X"
def set_pos(self, x, y):
self.x = x
self.y = y
def get_pos(self):
return (self.x, self.y)

class normal_class:
def __init__(self):
self.char = "Y"
class also_special_class:
def __init__(self):
self.char = "Z"
def set_pos(self, x, y):
self.x = x
self.y = y
def get_pos(self):
return (self.x, self.y)

string = "XYXZ"
dict = {"X": special_class(), "Y": normal_class(), "Z": also_special_class()}
ls = []
i = 0
while i < len(string):
k = 0
keys = list(dict.keys())
while k < len(keys):
if string[i] == keys[k]:
instance = dict[keys[k]]
if keys[k] == "X" or keys[k] =="Z": # i and k numbers that change
special_class = instance.set_pos(i, k) # why is special_class None?
### this code is ugly but it's the only way I know of doing it without errors
### however, the position of the two elements is not what I put into it initially
special_instance = dict[keys[k]]
special_instance.set_pos(i,k)
print(special_instance.get_pos())
instance = special_instance
ls.append(instance)
k += 1
i += 1
print()
print(ls)
print("nPosition after finished loop")
print(ls[0].get_pos())
print(ls[2].get_pos())

如果你能给我一些建议a( 为什么special_class的注释部分返回Noneb( 给出关于改进我的代码的建议,尤其是这部分

special_instance = dict[keys[k]]
special_instance.set_pos(i,k)
print(special_instance.get_pos())
instance = special_instance

c( 解释为什么我为get_pos获得相同的值,以及如何修复我的代码使其按预期工作,这将是令人惊叹的!!

您需要使用copy.deepcopy()来制作类对象的非浅层副本。这将添加类对象(kls(,而不是对它的引用

具体来说,在您的情况下,这样做应该可以解决问题。

from copy import deepcopy
ls.append(deepcopy(special_class))

示例

from copy import deepcopy
klasses = []
for _ in range(5):
#initialize the class object
kls = YourClass() 
klasses.append(deepcopy(kls))

对类定义的一些建议:

  1. 类名必须是CamelCased。有关更多详细信息,请参阅python类/变量/函数/方法命名约定PEP-8。

    # example
    class SpecialClass(object):
    def __init__(self):
    ...
    def some_method(self):
    ...
    
  2. 实例化至少带有括号的类;必要时,根据__init__()方法的要求,使用参数。例如,kls = SpecialClass只创建类的别名SpecialClass,名称为kls,而不实例化SpecialClass。要实例化,请改用:SpecialClass()

    # example
    kls = SpecialClass()    
    

最新更新