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!
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

Matthew Rigdon
8,223 PointsWhy do we use "self" for some functions and not on others?
What is the exact reason that we use "self" in some functions, and sometimes we don't. Here is an example.
class Combat:
dodge_limit = 6
attack_limit = 6
def dodge(self):
roll = random.randint(1, self.dodge_limit)
return roll > 4
def attack(self):
roll = random.randint(1, self.attack_limit)
return roll > 4
Notice how:
def dodge(self):
roll = random.randint(1, self.dodge_limit)
return roll > 4
Inherits self. Why don't you just write def dodge()? Also, inside of the code there is a regular variable, roll that isn't written as self.roll. When do you use self, and when do you not?
Thanks for the help!
1 Answer

Michael Vandenburg
6,952 PointsClass method definitions all show an argument that refers to the calling instance of that method. The dodge()
method uses the instance represented by the self object to determine which Combat
object's dodge_limit
to use as the maximum value for the roll.
You don't need to enter it inside the parentheses when you call it, though, because it's already specified. Say the game has two Combat
objects battling right now, Matthew
and Grendel
. You either called Matthew.dodge()
or Grendel.dodge()
. There's no reason to have to type Grendel.dodge(Grendel)
.
The Python doc for Classes is helpful. Referring to the example class
Python
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
it says "The call x.f() is exactly equivalent to MyClass.f(x)."
As for roll
vs. self.roll
, it's mainly a matter of scope. roll
is just a throwaway variable. Because of the way the game is structured, you don't want Grendel.roll
to be available for other code; you just want to know if the roll was a success or a failure. If you would decide to implement some kind of tiebreaker later where you need to know the last value rolled, you could use self.roll
instead, and it would work like attack_limit
and dodge_limit
. Calling Matthew.attack()
would set Matthew.roll
(but not return it), and Grendel.roll
is a separate value. (If you did implement that, you would probably want to name them more clearly, like self.last_attack_roll
and self.last_dodge_roll
.)