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 trialSebastiaan van Vugt
Python Development Techdegree Graduate 13,554 PointsNeed help using classmethod
My code is the following:
from dice import D20
class Hand(list):
def __init__(self, times):
self.times = times
@classmethod
def roll(cls, times):
list = []
for _ in range(times):
list.append(D20())
print(list)
return cls(list)
print(30*"*")
print(list)
print(30*"*")
@property
def total(self):
return sum(self)
rt = Hand.roll(3)
print(rt.total)
The list is correctly generated but can then not be made available to the total method. I must be doing something wrong but I do not know what. Any help is appreciated. Thank you.
1 Answer
Branden Ciranni
8,810 PointsI was able to make it work by calling super to initiate a list with dice objects:
class Hand(list):
def __init__(self, dice=None):
super().__init__(dice)
Although Hand
inherits list
, it does not contain any values unless they are added. Where you have
return cls(list)
this instantiates the Hand
class, but the list was actually stored in the times
class variable and not passed up to the list
super class.
Additionally, times
is not needed as a class variable as it is a parameter in roll()
.
Sebastiaan van Vugt
Python Development Techdegree Graduate 13,554 PointsSebastiaan van Vugt
Python Development Techdegree Graduate 13,554 PointsThank you for your help.
I finally got it to work like this:
It seems I indeed should not override the "times" variable.
A few things I found confusing though and I would like to ask a few follow-up questions. The first is about the list inheritance which is not a real inheritance since we don't have a list class. This seems to be simply a way to specify that the output should be a list. Is that right?
Furthermore, I don't understand what is happening with your init and super. "dice" is the name of the file and not that of a method or variable. Do I understand correctly that we usually use super to make a variable available in the parent class?
I was also long puzzled by the @classmethod but read that it would be appropriate in this situation and maybe now I understand why. I believe that we don't need to pass on anything to the dice app as long as we import the D20 method ("from dice import D20"). Since we however want to pass the variable (number of) "times" in the fashion "Hand.roll(3)" we need to use classmethod I believe. Simultaneously the output then becomes available to the total method. What is your take on this?
Branden Ciranni
8,810 PointsBranden Ciranni
8,810 Pointslist
is in fact a class that we have. It may not be in your file, and you may not import it, but it is a class built in to python. More info about lists here.The way I think about inheritance is this: A
list
is the most generic possible collection of objects. It has methods to add things, delete them, and so on and so forth. If we make a class that inherits thelist
class, it inherits all of these generic traits. It also becomes a collection of objects that has all of the properties of a list. However, in addition, we can add methods and properties to this new class, making it a special type of thelist
.For example, your
Hand
class is a list but it also has the roll method, and a property called total. It is just a special case of alist
with an added method and property.As for the use of
super()
, this is used to access a method of the parent class.Hand
is a child class of thelist
, and thus inherits all of its methods and properties. However, in order to access them, we have to make a call to the parent class usingsuper()
. So when I callwhat i am doing is initializing an instance of the class, using the super class' constructor. This creates our hand, with the same generic structure as the list, but also having the methods we have created, and being of type
Hand
.Finally, for class methods, I look at these like object factories. A class method lets you easily create an instance of your class. By calling
hand.roll(3)
we avoid the steps of individually creating each new dice object, then adding them to the hand. Instead, calling
Hand.roll(x)
will always immediately instantiate aHand
withx D20
objects. A class method always returns an instance of the class, so they are great for this purpose.I hope this helps.