0

I am working in Python 3.6 and have two classes, one class serves as a container for a list of the other, but the nested class does not inherit from the higher-order class. Basically here is a simplification of what I'm looking at:

class Library():

    def __init__(self, name, bookList):
        """
        Initializes a library class object
        Send: self (Library object), name (str), list of books in the library (list of Book objects)    
        """
        self.name=name
        self.bookList=bookList

class Book():
    def __init__(self, title, author, year):
        """
        Initializes a book class object
        Send: self (Book object), title (str), author (str), year (int)
        """
        self.title=title
        self.author=author
        self.year=year

    def owningLibrary(self):
        """
        Identifies the name of the library that owns the book
        Send: self (Book object)
        """
        #some code that looks at the library's name and returns it

if __name__=="__main__":

    #Create book
    warAndPeace = Book("War and Peace", "Tolstoy, Leo", 1869)
    hitchhikersGuide = Book("Hitchhiker's Guide to the Galaxy, The", "Adams, Douglas", 1985)

    #Create library
    orangeCountyLibrary = Library("Orange County Public Library", [warAndPeace, hitchhikersGuide])

    #Print the current owner of Hitchhiker's Guide
    print(hitchhikersGuide.owningLibrary())

My question is: How do I enable the contained object (book) to access the attributes/methods of the container object(library). In my example: to return the "name" variable of the owning library

What I've considered trying:

  • Inheritance+super() - but books aren't subclasses of libraries, libraries simply contain books
  • Maintaining library characteristics on each book object - but this seems clunky and duplicates data across the library and book objects

I'm sure there is something obvious that I'm missing, but everything I've searched for seems to come back with recommendations for inheritance which doesn't seem to make sense to me. Thanks for your help!

2
  • When adding the book to the library, set a property on the book that references the library of which it is part of? kindof per Book.SetLibrary(lib) and a __myLibrary__ inside Book Commented Dec 29, 2017 at 18:57
  • 1
    owningLibrary doesn't seem like a method Book should even have. Commented Dec 29, 2017 at 18:59

3 Answers 3

1

Add to Book.__init__:

self.library = None

Add to owningLibrary:

if self.library is None:
    return "No Library"
return self.library.name

Add to Library.__init__:

for book in self.bookList:
    book.library = self

There is no way for the Book to know what Library it's in without it having an attribute that tells it. The Library instance then needs to tell all of the books what library contains them.

Sign up to request clarification or add additional context in comments.

Comments

0

Since Library and Book are "definition-wise" independent, you have to create a reference to a library from a book explicitly.

One solution could be to add library field to the Book class, which will store the name of a library (or reference to Library object, depends on what you plan to do further). That can be done in the Library __init__:

class Library:
    def __init__(self, name, book_list):
        """
        Initializes a library class object
        Send: self (Library object), name (str), list of books in the library (list of Book objects)    
        """
        self.name = name
        self.bookList = book_list
        # set reference to the name of this library for every added book
        for book in book_list:
            book.library = self.name


class Book:
    def __init__(self, title, author, year):
        """
        Initializes a book class object
        Send: self (Book object), title (str), author (str), year (int)
        """
        self.title = title
        self.author = author
        self.year = year
        self.library = None  # book does not belong to any library yet


if __name__ == "__main__":
    # Create book
    warAndPeace = Book("War and Peace", "Tolstoy, Leo", 1869)
    hitchhikersGuide = Book("Hitchhiker's Guide to the Galaxy, The", "Adams, Douglas", 1985)

    # Create library
    orangeCountyLibrary = Library("Orange County Public Library", [warAndPeace, hitchhikersGuide])

    # Print the current owner of Hitchhiker's Guide
    print(hitchhikersGuide.library)  # Orange County Public Library

If it is possible for a Book to be in multiple libraries at the same time:

  • initialize self.libraries = [] instead of self.library = None;
  • in Library constructor do book.libraries.append(self.name) instead of book.library = self.name.

Comments

0

the way i would do this is:

    class Library:
        def __init__(self, name):
            self.name=name
            self.books=[]
    class Book:
        def __init__(self, title, author, year, library):
            self.title=title
            self.author=author
            self.year=year
            self.library=library
            self.library.books.append(self)#put this book in the library
    # Create library
    orangeCountyLibrary = Library("Orange County Public Library"
    # Create book
    warAndPeace = Book("War and Peace", "Tolstoy, Leo",
    1869,orangeCountyLibrary)
    hitchhikersGuide = Book("Hitchhiker's Guide to the Galaxy, The",
    "Adams, Douglas", 1985,orangeCountyLibrary)
    # Print the current owner of Hitchhiker's Guide
    print(hitchhikersGuide.library)  # Orange County Public Library
this is the way tkinter handles connecting Canvas instances to Tk instances.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.