为什么 append 方法修改 class in python 中的变量?

Why does append method modify a variable within a class in python?

我正在尝试理解 python 中的 class 类型。就在我以为我理解它的时候,我发现了这个。我不明白为什么当我使用 append 方法时,它会为其他变量保存。示例:

class flower:
    tpe="standard"
    register=[]
     
    def __init__(self):
        pass
    
amapola=flower()
amapola.register.append("Amapola")
amapola.tpe="spring"
print(f"Type: {amapola.tpe}, register= {amapola.register}")

cactus=flower()
cactus.register.append("Cactus")
print(f"Type: {cactus.tpe}, register= {cactus.register}")

输出:

Type: spring, register= ['Amapola']
Type: standard, register= ['Amapola', 'Cactus']

我不明白为什么“amapola”会出现在“仙人掌”名录中。我认为当创建变量“仙人掌”时,列表将被设置为零。或者另一方面,如果寄存器在被变量“amapola”修改时被保存,为什么在“仙人掌”中它returns到“标准”而不是“spring”,如果它之前也被修改过?

每个实例共享 相同 列表,由 class 属性 register 引用。如果您希望每个实例都有自己的寄存器,通过在 __init__.

中定义 self.register = [] 使其成为实例属性
class flower:
    tpe="standard"
     
    def __init__(self):
        self.register = []

当您编写 amapola.tpe = "spring" 时,您正在创建一个新的实例属性,该属性 遮蔽 class 属性 tpe。您也可以去掉 class 属性并在 __init__ 中定义 tpe

class flower:
    tpe="standard"
     
    def __init__(self, tpe="standard"):
        self.register = []
        self.tpe = tpe

amapola=flower("spring")
amapola.register.append("Amapola")
print(f"Type: {amapola.tpe}, register= {amapola.register}")

cactus=flower()
cactus.register.append("Cactus")
print(f"Type: {cactus.tpe}, register= {cactus.register}")

另一方面,如果register确实应该共享的,那么flower.register包含您定义的所有实例的名称,然后将 register 保留为 class 属性。 amapola.register.append 不是对名称的 赋值 ;这是一种 改变 现有值的方法。