1

Suppose I have something like:

class Dog:
   name = ""
   weight = 0
   def __init__(self,name,wg):
       self.name = name
       self.wg = wg

def feed(pet):
   pet.weight = pet.weight + 5
   if pet.weight > 20:
       print("your dog would get too fat")
   else:
       print("it is safe to feed your dog")

my_dog = Dog("sparky",10)
feed(my_dog)

Is there anyway to have it so that the changes to pet.weight are not transferred to my_dog.weight?

I want the function to be able to take information from a class instance, perform calculations, and then leave the original instance unchanged.

1 Answer 1

2

You are reassigning the value of the pet.weight attribute on this line:

pet.weight = pet.weight + 5

Doing this affects the pet instance even after the code has returned from the feed function.

To fix the problem, simply create a local name that is equal to pet.weight + 5 and work with that instead:

def feed(pet):
   weight = pet.weight + 5
   if weight > 20:
       print("your dog would get too fat")
   else:
       print("it is safe to feed your dog")

Now, we use the value of pet.weight but avoid changing it.


Also, you have defined your class incorrectly. By doing this:

class Dog:
   name = ""
   weight = 0

you have made name and weight to be class attributes of Dog. This means that their values will be shared among all instances of Dog and modifying them will affect all instances. In other words, all of your Dogs will have the same name and weight.

But then you do:

def __init__(self,name,wg):
    self.name = name

which overshadows the class attribute name with an instance attribute of the same name. Unlike class attributes, instance attributes are unique to each instance of a class. So, weight is still a class attribute (shared by all Dogs) while name is now an instance attribute (unique to each Dog).

I think it would be best if you removed those lines and wrote the Dog class like so:

class Dog:
   def __init__(self, name, weight):
       self.name = name
       self.weight = weight

Now, name and weight are both instance attributes. Each Dog has a unique name and weight and changing either of those values on one Dog will no longer affect the other Dogs.

For more information on this, you can check out these sources:

Sign up to request clarification or add additional context in comments.

2 Comments

In fact, his attributes will not be shared in practice, because he assigns them in __init__. This will create instance attributes that hide the class attributes. However, you're right that it's better to remove the class attributes, since it can lead to confusing attribute-sharing behavior if the instance attribute is deleted (or if a mutable class attribute is mutated instead of reassigned).
Right, I have clarified. I think the OP may have thought that he needed to pre-assign the name and weight attributes before assigning them in __init__.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.