Reputation: 7
I’m new to Python and OOP (& StackOverflow), so excuse me if the question is too naïve, but I can’t seem to get it solved on my own. I’ve just written a very simple program to see how OOP works, which I reproduce below:
from System import *
class trial(object):
def __init__(self, counter):
self.counter = counter
def passon(self):
p = person(self.counter)
p.increase()
class person(object):
def __init__(self, counter):
self.counter = counter
def increase(self):
self.counter +=1
return self.counter
I call the function like this:
t = trial(2)
t.passon()
I was expecting the value of counter to updated automatically in class trial, however when I type t.counter, it still returns 2. But if I write:
p = person(t.counter)
p.increase()
then p.counter becomes 3. How do I increase the value of counter in class trial? I know I am making some elementary mistake here, but I’d appreciate any help.
Upvotes: 1
Views: 216
Reputation: 81988
Your issue has to do with how Python treats objects -- some are immutable (you can't change them, you can only replace them) and some are mutable (you can change their internal state).
(If you know about references and pass by value vs. pass by reference etc. ints, floats, strings and tuples are like pass by value, (almost) everything else is mutable).
ints are "immutable" which means that when you perform some operation on it, it is actually returning a new copy (it can also be a cached value) of the int.
So this:
self.counter = self.counter + 1
is almost like this
self.counter = new int(counter + 1) # I know, "new" isn't pythonic,
#but it is clearer in OOP with the int function.
So, since self.counter is not the same thing which was originally passed to it, there is no way to have both p and t point to the same object.
The solution? Make Trial have a Person as a property:
from System import *
class trial(object):
def __init__(self, counter):
self.person = person(counter)
def passon(self):
p.increase()
class person(object):
def __init__(self, counter):
self.counter = counter
def increase(self):
self.counter +=1
return self.counter
t = trial(2);
t.person # <!-- this is your person object.
t.passon()
print(t.person.counter) # 3
t.passon()
print(t.person.counter) # 4
Upvotes: 0
Reputation: 123393
Each of your classes has a separate counter
attribute. If you want to update the trial
object's counter with the result of calling p.increase()
, you would need to do something similar to this in passon()
:
def passon(self):
p = person(self.counter)
self.counter = p.increase()
Upvotes: 0
Reputation: 29093
I believe that each class has it's own counter. Modify your 'passon' function the following way and you will see this:
def passon(self):
p = person(self.counter)
print 't', self.counter
print 'p', p.counter
p.increase()
print 'p', p.counter
print 't', self.counter
Upvotes: 1
Reputation: 798456
Integers in Python are immutable. Pass the trial
to the person
, and increment the attribute on the saved trial
instead.
Upvotes: 4