Friday, May 13, 2022

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

Issue

I am trying to understand the class type in python. And just when I thought I understood it, I find this. I don't understand why when I use the append method it is saved for other variables. Example:

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}")

Output:

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

I don't understand why "amapola" is listed in the "cactus" register. I thought that when the variable "cactus" was created, the list would be set to zero. Or on the other hand, if the register was saved when modified by the variable "amapola", why in "cactus" it returns to "standard" instead of "spring" if it was modified before too?


Solution

Every instance shares the same list referenced by the class attribute register. If you want each instance to have its own register, make it an instance attribute by defining self.register = [] in __init__.

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

When you write amapola.tpe = "spring", you are creating a new instance attribute that shadows the class attribute tpe. You may as well get rid of the class attribute and define tpe in __init__ as well.

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}")

On the other hand, if register really is supposed to be shared, so that flower.register contains the names of all the instances you define, then keep register as a class attribute. amapola.register.append is not an assignment to a name; it's a method that mutates an existing value.



Answered By - chepner
Answer Checked By - Mildred Charles (PHPFixing Admin)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.