0

I am having some issues with the classes below:

class book:
    def __init__(self,name=None):
        self.name=name
        return
    
class bookshelf:
    def __init__(self,books=[]):
        self.books=books
        return
    def add_book(self,name):
        self.books.append(
            book(name)
        )
        return

Next, I initialize list a list of bookshelves:

bookshelves = [bookshelf() for i in range(3)]

With all of them empty, both bookshelfs[0].books and bookshelfs[1].books are [].

However, after adding a book to the first bookshelf,

bookshelves[0].add_book('Book1')

all books have a book named "Book1": both bookshelves[0].books[0].name and bookshelves[1].books[0].name have the value 'Book1'.

This does not change even after I reinitialize the list of bookshelf. But if I rerun the section defining the classes, the bookshelfs will be cleared.

Any ideas how does this happen? How should I implement this part correctly? By the way, I am running Python 3.8.3 .

ZL-Arctic
  • 109
  • 7

1 Answers1

1

Python Mutable Default Arguments are counter-intuitive! Python creates the list once when the method is defined not when it is called. Therefore the list obj is shared between instances. Here's A good article on the issue.

I would instead remove the default argument and check/set it in the init method.

class bookshelf:
    def __init__(self,books):
        self.books = []
        if books:
            self.books = books
        
TheLazyScripter
  • 2,541
  • 1
  • 10
  • 19