Reputation: 1495
As I'm tying to understand the python self concept, I came across this example that I thought was helpful. But there is one part that confuses me. Why does print a.i
output two different values? In the first case the output is 5
which makes sense to me. But then a few lines later the same print a.i
statement outputs 123
.
def say_hi():
return 'hi!'
i = 789
class MyClass(object):
i = 5
def prepare(self):
i = 10
self.i = 123
print i
def say_hi(self):
return 'Hi there!'
def say_something(self):
print say_hi()
def say_something_else(self):
print self.say_hi()
Output
>>> print say_hi()
hi!
>>> print i
789
>>> a = MyClass()
>>> a.say_something()
hi!
>>> a.say_something_else()
Hi there!
>>> print a.i
5
>>> a.prepare()
10
>>> print i
789
>>> print a.i
123
Upvotes: 3
Views: 129
Reputation: 41670
You are using global, local and instance attributes with the same name:
def say_hi(): # This is the global function 'say_hi'
return 'hi!'
i = 789 # This is the global 'i'
class MyClass(object):
i = 5 # This is a class attribute 'i'
def prepare(self):
i = 10 # Here, you are creating a new 'i' (local to this function)
self.i = 123 # Here, you are changing the instance attribute 'i'
print i # Here, you are printing the new'ed 'i' (now with value 10)
def say_hi(self): # This is the object method 'say_hi' function
return 'Hi there!'
def say_something(self):
print say_hi() # Here, you are calling the global 'say_hi' function
def say_something_else(self):
print self.say_hi() # Here, you are calling the object method 'say_hi' function
So the ouput is correct:
>>> print say_hi() # global
hi!
>>> print i # global
789
>>> a = MyClass()
>>> a.say_something() # say_something calls the global version
hi!
>>> a.say_something_else() # say_something_else calls the object version
Hi there!
>>> print a.i # class attribute 'i'
5
>>> a.prepare() # prints the local 'i' and change the class attribute 'i'
10
>>> print i # global 'i' is not changed at all
789
>>> print a.i # class attribute 'i' changed to 123 by a.prepare()
123
Upvotes: 5
Reputation: 369424
Before the following statement in prepare
method:
self.i = 123
self.i
references a class attribute MyClass.i
(because the instance attribute is not set)
Once the self.i = ..
statement is executed, self.i
reference a new value 123
. (This does not affect the class attribute MyClass.i
, making a new instance attribute)
Upvotes: 4
Reputation: 1402
You are changing the class variable i to 123 in the prepare()
function:
self.i = 123
After which you are calling the class variable by doing print a.i
which will print 123 as a result.
Upvotes: 2