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

Python Object-Oriented Python Advanced Objects Constructicons

Flore W
Flore W
4,744 Points

create_bookcase without the classmethod AttributeError

In Teacher's Notes on the "Constructicons" video, Kenneth writes the code that we could have written if we didn't define a classmethod:

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

    def __str__(self):
        return "{} is by {}".format(self.title, self.author)

class Bookcase2:
    def __init__(self, books = None):
        self.books = books

    def create_bookcase2(self, book_list):
        for title, author in book_list:
            self.append(Book(title, author))
        return self

I tried running this code in the console and it gave me an AttributeError:

>>> from books import Bookcase2
>>> bc = Bookcase2().create_bookcase([('Hamlet','Shakespeare'), ('Persuasion','Austen')])
Traceback (most recent call last):                                                               
  File "<stdin>", line 1, in <module>                                                            
  File "/home/treehouse/workspace/books.py", line 29, in create_bookcase2                        
    self.append(Book(title, author))                                                             
AttributeError: 'Bookcase2' object has no attribute 'append'

What am I doing wrong here? Thanks in advance for the help!

Jessica Solano
Jessica Solano
6,987 Points

Same! Would love a breakdown of this?

3 Answers

Mahbub Aziz
Mahbub Aziz
13,410 Points

This is how I have done. Although its working magically, not sure how the Bookcase class is using Book class without any inheritance!! Can someone please explain?

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

    def __str__(self):
        return '{} by {}'.format(self.title, self.author)


# ---------------------------------- classmethod(Bookcase) vs self(Bookcase2) ----------------------------- 

class Bookcase:
    def __init__(self, books=None):
        self.books = books

    @classmethod
    def create_bookcase(cls, book_list):
        books = []
        for title, author in book_list:
            books.append(Book(title, author))
        return cls(books)



class Bookcase2():
    def __init__(self):
        self.books = []

    def create_bookcase2(self, book_list):
        for title, author in book_list:
            self.books.append(Book(title, author))
# ---------------------------------------------------xxx-----------------------------------------
Ayman Said
seal-mask
.a{fill-rule:evenodd;}techdegree
Ayman Said
Python Web Development Techdegree Student 14,717 Points

Hi Mahbub Aziz, regarding your question: "how the Bookcase class is using Book class without any inheritance!!" you agree with me on the fact that Book & Bookcase are both reside in the same module (book.py). therefore both classes have mutual access in the module code to each class. From the python shell Kenneth has imported the class Bookcase only which naturally has access to the other classes in the same module in case the class Bookcase access them (and as we see it does). and that's totally fine.

Hope this helps.

Mahbub Aziz: The Bookcase consists of multiple Books. Inheriting from it would make sense if every Bookcase is also a Book.

Hi Flore W,

The Exception was raised because you called append on an instance of Bookcase2:

AttributeError: 'Bookcase2' object has no attribute 'append'

which happened on line 29:

File "/home/treehouse/workspace/books.py", line 29, in create_bookcase2

On line 29 inside of create_bookcase2 you call append on self:

for title, author in book_list:
            self.append(Book(title, author))

self is the instance of Bookcase2 not the list. To access the list on self call self.books which has append method.

Correction

for title, author in book_list:
            self.books.append(Book(title, author))