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 trialdoesitmatter
12,885 PointsWhy use @classmethod?
In the video Kenneth says that you do not want to pass a mutable argument as an argument when initializing the class. I don't get why?
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __str__(self):
return "{} by {}".format(self.title, self.author)
class BookCase:
def __init__(self, books=None):
self.books = books
@classmethod
def create_bookcase(cls, books):
list_of_books = []
for t, a in books:
list_of_books.append(Book(t, a))
return cls(list_of_books)
my_bookcase = BookCase([Book("Alice In Wonderland", "Lewis Carroll"),
Book("Sherlock Holmes", "Arthur Conan Doyle"),
Book("The Stranger", "Albert Camus")])
for i in my_bookcase.books:
print(i)
my_bookcase_2 = BookCase.create_bookcase([("Alice In Wonderland", "Lewis Carroll"),
("Sherlock Holmes", "Arthur Conan Doyle"),
("The Stranger", "Albert Camus")])
for i in my_bookcase_2.books:
print(i)
In the code above I achieve the exact same thing with my_bookcase
as with my_bookcase_2
which uses the create_bookcase
classmethod, so what is the point of using a classmethod?
And finally, why is books = None
used instead of just books
inside of the __init__()
?
class BookCase:
def __init__(self, books=None):
self.books = books
4 Answers
Chris Freeman
Treehouse Moderator 68,457 PointsIn this case, it is possible to do without the classmethod. The lesson is about the general use of classmethods and simple examples might seem contrived or trivially bypassed. In a more complicated example, the create_bookcase
classmethod might provide more validation of the incoming books or add other attributes that might not be obvious outside of the Book
class..
The books=None
allows someone to create a bookcase instance without any supplied books. Since books
is used in the __init__
code, it needs to have a default value or it will raise a NameError
.
Post back if you have more questions!
Huston Petty
2,833 PointsA better example, like the one above by Chris, needs to be used in the video. The one in the video is confusingly simple. I struggled for like 10 minutes to understand WHY you would want to create a class method that appeared to do exactly what __init__
would do. I kept asking myself "Why not just put all of that in the __init__
?!". Maybe the video example just needs to show a few different class methods to show why they are useful. Like, a create_bookcase
vs create_sorted_by_author_bookcase
vs create_sorted_by_title_bookcase
. Just a thought.
Chris Freeman
Treehouse Moderator 68,457 PointsNice feedback! Tagging Craig Dennis
Craig Dennis
Treehouse TeacherThanks Chris Freeman and Huston Petty ! Added to refresh notes!
Aaron Banerjee
6,876 PointsChris Freeman, so does the __init__
method interact with the class method to instantiate the data in the example above?
Chris Freeman
Treehouse Moderator 68,457 PointsThe final statement in the class method is of the form
return cls(data)
It is this call within the class method that instantiates the class and subsequently calls the __init__
method.
Chul Kim
2,341 PointsAre class methods mostly used with parameters that are mutable?
I don’t know if I am understanding this correctly..it seems that there are two ways to control how instances are created.
The first, changing the __init__
method which controls how the parameters are applied and defined to the instance.
The second, you can use the same __init__
method except with the use of class methods you can decide which parameters get passed into the __init__
method which in turn you can create different instances with different parameters??
Chris Freeman
Treehouse Moderator 68,457 PointsUnsure what you mean by mutable parameters, since all parameters are mutable. Even parameters that are protected as properties
through setters and getters maybe modified by both class methods and instance methods.
Many times a classmethod is used in the constructor process to run code before __init__
is run. But in general, a class method is used when you have a function that needs to executable before the instance is created.
This StackOverflow post talks through many uses for @classmethod
.
One additional clarification: __init__
doesn’t create the instance, rather it modifies the instance after creation (which is why it dos not have a return statement). The __new__
method (typically inherented from object
) creates the actual instance. __new__
calls __init__
and returns the new instance.
Pete P
7,613 PointsPete P
7,613 PointsBased off of your answer, I'm wondering if this would be an example of where classmethods should be used.
Let's say I have a class that takes a file name as an argument. This file name could refer to a text file, excel file, or csv file. I need to perform different operations and set attributes differently based upon the type of file that is passed to the class.
So, rather than doing something like in this pseudo code:
I could (should?) define classmethods to handle each file type
Or am I way off? Thanks for all of your help!
Chris Freeman
Treehouse Moderator 68,457 PointsChris Freeman
Treehouse Moderator 68,457 PointsGreat follow-up question! It's helped me think more about how I would decide when to use a classmethod over an instance method. I came to this conclusion:
If a classmethod is intended to operate on the
class
and a regular instance method is intended to operate on an
instance
of the class, then a classmethod is best used to for functionality associated with the class, but that would not be useful if applied to an existing instance of a class. One example is
helping construct specific classes instances
.`So in your example, I would have the
__init__
method create the class from a data set and use the classmethods to prep the data set used by the__init__
method. Restructure it more like:This StackOverflow question lists other examples on where classmethods are useful.
Hope this makes sence. As always, post back as needed!
Pete P
7,613 PointsPete P
7,613 PointsMakes sense. Completely cleared up my confusion. Thanks again!