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 Rigdon8,223 Points
Why 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
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!
Michael Vandenburg6,952 Points
Class 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
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,
Grendel. You either called
Grendel.dodge(). There's no reason to have to type
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)."
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
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