Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial

Elizabeth McInerney
3,175 PointsObject Oriented Python, __init__ , and self.argument
I am trying to understand when you need a self.argument for an instance of a class, and when you do not. Prior to using init, we were able to have instances such as jubjub = Monster() and then look at attributes such as jubjub.color, without using self.color. It is looking to me like you use self.attribute whenever you are inside a Method. But in the final monster game, I see a variable called player_choice inside the player_turn Method, and that variable name does not have a self modifier, so I am confused.
8 Answers

Chris Freeman
Treehouse Moderator 68,468 Pointsself
refers to an instance. When attributes are added to a class they are referred to as an attribute of that object using self
. Since players_choice
is not intended to become used as a persistent attribute, a local variable works.
class Monster():
# class attributes
height = '6'
color = 'blue'
def change_color(self, newcolor):
'''Change monster color'''
self.color = newcolor
# new instance
dragon = Monster()
dragon.color # will be blue
dragon.change_color('green')
dragon.color # will be green
In this code, dragon
has the same methods as Monster'. When
dragon.change_color()is called, the method needs to know which instance of Monster is changing colors. Python realizes this and automatically passes the instance as the first parameter. This instance reference is assigned to
selfduring the method execution. Now
self.color` is referencing the color of this dragon instance.
self
is used to reference attributes of an object. If a variable is not indented to persist with the instance for later use, there isn't a need to make it an attribute using self
Ready to Stretch Your Mind?!?
The "class variables" are in their own namespace. That is, when the instance dragon
changes colors or add other attributes, they are part of the instance namespace and not the base class Monster()
. Here an example from ipython
:
in [157]: class Monster():
.....: color = 'blue'
.....: def change_color(self, newcolor):
.....: self.color = newcolor
.....:
In [158]: dragon = Monster()
In [159]: dragon.color # class color
Out[159]: 'blue'
In [160]: dragon.color = 'green'
In [161]: dragon.color # instance color overrides (not overwrites) class color
Out[161]: 'green'
In [162]: del dragon.color # delete instance attribute
In [163]: dragon.color #color reverts to class color
Out[163]: 'blue'
In [164]: Monster.color = 'cyan' # change color at the base class
In [165]: dragon.color # color changes too because it has no instance color so references class color
Out[165]: 'cyan'

Pete Jeffryes
5,752 PointsI'll take a stab at this :)
Using self is necessary to access the instance itself while writing methods and creating attributes. Self gives you the ability to have different names for the instances. If you used jubjub while writing your methods and attributes instead of self, you could only ever have an instance called jubjub. But with self you can call it anything when you create and instance and still access your attributes/methods.
self.color will only be used in writing the attribute/method, but you must use the jubjub.color or whatever the particular instance is called to access that specific instance.
The use of init does not necessarily change this. init allows you to inherit from another class while also defining new initialize attributes.
I hope this helps. This is how I understand it, but am certainly no expert. I would enjoy hearing some more explanation on these topics. Cheers.

Elizabeth McInerney
3,175 PointsHmm, I am not sure I get what you have stated here. I feel like I could create a class called Monster. Then type color = 'yellow' (without using self), then use a def init(self) to define a weapon to be a sword (using self). Then if I create an instance called jubjub by typing jubjub = Monster(), I would find that the color is yellow and the weapon is a sword. So self is not necessary for creating attributes outside of methods. I can create any number of monsters this way, with different names, and they would all have the color yellow, without ever using self. Self is only necessary inside methods, and I understand that it is needed there.
So, I am wondering how the instructor got away with not using the self modifier inside the method player_turn.
Thanks for your input!

Elizabeth McInerney
3,175 PointsI think that self.variable is not needed for a variable that is only used inside of the method. Perhaps you need to use self.variable with variables that are passed around the class, inside and outside of methods.

Elizabeth McInerney
3,175 PointsHold on, wait, wait, wait, I don't have a very stretchable mind! Let me go back and ask - if I make a class called Monster, and then set the color to 'yellow' without doing anything else, no def init, etc. Then I go to my console and make a Monster called jubjub. Is jubjub an instance of Monster? Is color an attribute of jubjub? In this very simple case, I can reference the an attribute of jubjub without using self, correct? I only need self when I am passing instances into methods, because the method needs to know which instance to deal with, correct?

Chris Freeman
Treehouse Moderator 68,468 Pointsif I make a class called Monster, and then set the color to 'yellow' without doing anything else, no def init, etc. Then I go to my console and make a Monster called jubjub. Is jubjub an instance of Monster? Yes!
Is color an attribute of jubjub? Yes, though since it did not set it within the instance, it inherits it from Monster.
In this very simple case, I can reference the an attribute of jubjub without using self, correct? Yes and no. In refering to jubjub in other code you can use jubjub.self
, when referreing to color within methods of jubjub
you will need to use self.color
I only need self when I am passing instances into methods, because the method needs to know which instance to deal with, correct? Yes, if you mean need self
as in it being the first argument of a defined method parameter list.
Think about this: color is an attribute of an object. You access it by identifying instance DOT color
whether that be self.color
or dragon.color

Elizabeth McInerney
3,175 PointsI wrote the questions above because you said "self is used to reference attributes of an object". My point is that self is not always used. Is that correct? If you have very simple code like I described above, Python operates without using self, correct? You only need to bring in self when you start adding methods and passing arguments into and out of them, correct?

Elizabeth McInerney
3,175 PointsThanks for ans my question about when you do not use self inside methods. It looks like I figured that one out correctly, that self is not needed on a variable that is not an attribute of the instance and that is only being used locally (within the method).

Elizabeth McInerney
3,175 Points"When dragon.change_color()is called, the method needs to know which instance of Monster is changing colors. Python realizes this and automatically passes the instance as the first parameter."
So this is what I find confusing. Why does Python need to pass the instance as the first parameter (self), when the instance was spelled out at the front of dragon.change_color()?

Chris Freeman
Treehouse Moderator 68,468 PointsGetting deeper! Hang on...
change_color()
is a method of the class Monster
. There are not multiple versions of this code hanging around. There is just the version that is attached to the base class. An instance doesn't get its own copy, rather python points dragon.change_color() to the class method Monster.change_color()
. The passed self
is how this single piece of code can tell which instance it is actually operating on.
Similar to the "brain expanding" example of class verses instance color attributes, the change_color() methods also use the same process where an instance method overrides (not overwrites) the class method. It would seem possible if dragon created its own instance version for change_color()
that it would need self
, since, it is the dragon's version. To keep the paradigm method usage the same, self
is passed to both. self
is also needed to differentiate attributes of dragon from local variables in the dragon method code.

Elizabeth McInerney
3,175 PointsSo what I find confusing is that when you type out dragon.change_color() it is already clear what self is (an instance called dragon). I would think that Python could grab that information from dragon.change_color() and pass it through on it's own, without having to require the programmer to pass self as an argument. It is sort of like asking someone to pass out pictures of themselves so that people know what they look like, when all the receiver of the picture needed to do was to look at the giver.

Elizabeth McInerney
3,175 PointsOK, I am ready to stretch my mind. So it seems from your example that when you use dragon.color = 'green' you are setting to a fixed variable, but when the dragon is getting it's color from the class, it is pointing to a color location in class that will change whenever someone changes the variable in that location.

Chris Freeman
Treehouse Moderator 68,468 PointsVery close.
When referencing dragon.color
, python first looks in the instance attributes, then in the class attributes to get the value.
When setting dragon.color
, python always sets the instance attribute. The class attribute is not affected. This happens whether the code uses dragon.color = 'green'
or whether there is a method called such as dragon.change_color('green')
. Since the self
passed to the change_color()
method refers to the instance and self
is the dragon instance, self.color
will change the instance attribute.
So when using dragon.color = 'green'
, the instance attribute is set to the string 'green'. More accurately, the instance attribute is set to a pointer to an object that is a string 'green'. Everything is an object and all assignments are actually pointers to other objects. You can use id(some_object)
to see the "id" of the object.
Going deeper still.... Let's look at the object IDs as the colors are changed. Ignore this if it "to deep".
In [187]: Monster.color #get class color
Out[187]: 'blue'
In [188]: id(Monster.color) # id class color
Out[188]: 140054661784104
In [189]: dragon.color # get instance color
Out[189]: 'cyan'
In [190]: id(dragon.color) # id instance color
Out[190]: 140054662210032
In [191]: id('blue') # id string "blue"
Out[191]: 140054661784104
In [192]: id('cyan') # id string "cyan"
Out[192]: 140054662210032
In [193]: del dragon.color # delete instance color attribute
In [194]: dragon.color # get instance color does not exist, python uses class color
Out[194]: 'blue'
In [195]: id(dragon.color) # id instance color which is now class color
Out[195]: 140054661784104
In [196]: Monster.color = 'red' # change class color
In [197]: id(Monster.color) # id new class color
Out[197]: 140054662212832
In [198]: id('red') # id string 'red'
Out[198]: 140054662212832
In [199]: id(dragon.color) # id instance color attribute
Out[199]: 140054662212832
In [200]: dragon.color = 'blue' # set instance attribute
In [201]: id(dragon.color) # id new instance color attribute
Out[201]: 140054661784104
In [210]: id('black') # id some other string
Out[210]: 140054661568584
In [211]: id('black') # id same string
Out[211]: 140054661568360
In [212]: id('black') # id same string
Out[212]: 140054661568640
Whoa! Why is the id
for "black" changing? Since this string is not referenced (by a pointer created during some previous assignment), that is, its "reference count" is zero, the string object is tossed and its memory space is recovered during garbage collection. At the next id('black')
, a new string is created at some other location. If an object attribute is set to 'black' then the string created would persist and all others needing a string 'black' would reference the same memory location.

Elizabeth McInerney
3,175 PointsWow, cool, I actually got this! Thanks! Everything is an object, every argument is a pointer. The pointing is like a family tree, with the top of the tree being a location number (where that family is located) and then with other things descending but with arrows pointing back to the top (the location). If an object does not settle down with a family, then it moves around.