2

When calling on a new instance of an object for a class I've created, my one instance of the class is just being overwritten. Why could this be? Example is below.

My class is defined as follows:

class my_class: attribute = "" examples = [] children = [] d = {} def __init__(self, attribute, e): self.attribute = attribute self.examples = e for ex in self.examples: self.d[ex[-1]] = self.d.get(ex[-1], 0) + 1 

I am making an initial instance as such:

root = my_class(some_attribute, data) 

Then, I create another instance as such:

child = my_class(different_attribute, root.examples[somewhere_1:somewhere_2]) 

In the end, my initial 'root' is now somehow identical to 'child', where 'root' should have gone unchanged. Why is this!?

2 Answers 2

7

I don't think you are doing with the initializations of attribute, examples, children and d what you think you are doing. Those are now attributes of the class, not of each instance. If you want each instance of the class to have its own attributes for attribute, examples, children and d, you should instead write:

class my_class: def __init__(self, attribute, e): self.attribute = attribute self.examples = e self.children = [] self.d = {} for ex in self.examples: self.d[ex[-1]] = self.d.get(ex[-1], 0) + 1 
Sign up to request clarification or add additional context in comments.

Comments

2

When you define variables in the class definition, they are class attributes.

>>> my_class.examples is my_class().examples True 

(is checks that they are exactly the same object, not just equal. For example, True == 1, but True is not 1.)

As lists and dicts are mutable, this means that changes in my_class.examples or root.examples or child.examples will be reflected in all the others.

The way you should do such a thing is by setting it inside the constructor:

class my_class: def __init__(self, attribute, e): self.attribute = attribute self.examples = e self.children = [] self.d = {} for ex in self.examples: self.d[ex[-1]] = self.d.get(ex[-1], 0) + 1 

You probably also wish to replace self.examples = e with self.examples = e[:] which will make a shallow copy of the list. Otherwise:

>>> data [1, 2, 3, 4, 5] >>> root = my_class(some_attribute, data) >>> root.examples [1, 2, 3, 4, 5] >>> data += [6, 7] >>> root.examples [1, 2, 3, 4, 5, 6, 7] >>> # ... because: >>> root.examples is data True 

Side-note: the recommended Python style would have your class as MyClass. I recommend that you read PEP 8.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.