Christopher Moskovitz
Christopher Moskovitz

Reputation: 47

Instantiating a subclass python

Just a simple class definition withh subclasses to show inheritance

import datetime

class LibaryItem:        #The base class definition
    def __init__(self, t, a, i):  # initialiser method
        self.__Title = t
        self.__Author_Artist = a
        self.__ItemID = i
        self.__OnLoan = False
        self.DueDate = datetime.date.today()

    def GetTitle(self):
        return(self.__Title)
# All other Get methods go here

    def Borrowing(self):
        self.__OnLoan = True
        self.__DueDate = self.__DueDate + datetime.timedelta(weeks = 3)
    def Returning(self):
        self.OnLoan = False
    def PrintDetails(self):
        print(self.__Title, '; ', self.__Author_Artist,'; ',end='') # end='' Appends a space instead of a newline
        print(self.__ItemID, '; ', self.__OnLoan,'; ', self.__DueDate)

class Book(LibaryItem):# A subclass definition
    def __init__(self, t, a, i):  # Initialiser method
        LibaryItem.__init__(self, t, a, i) 
        # This statement calls the constructor for the base class

        self.__IsRequested = False
        self.__RequestBy = 0
    def GetIsRequested(self):
        return(self.__IsRequested)
class CD(LibaryItem):
    def __init__(self, t, a, i): # Initialiser method
        LibaryItem.__init__(self, t, a, i)
        self.__Genre = ""
    def GetGenre(self):
        return(self.__Genre)
    def SetGenre(self, g):
        self.__Genre = g

Instantiating a subclass

ThisBook = Book('Title', 'Author', 'ItemID')

ThisCD = CD('Title', 'Author', 'ItemID')

This is my problem here I don't understand why the ThisBook the object's attribute doesn't change from False its default value to True.

# Using A method
print(ThisBook.GetIsRequested())

ThisBook.IsRequested = True
print(ThisBook.GetIsRequested())

Thank you a reason to why this doesn't work would be helpful

Upvotes: 2

Views: 594

Answers (2)

Nils Werner
Nils Werner

Reputation: 36739

You probably meant to do

ThisBook.__IsRequested = True

which you can't do because of name mangling. You could write another setter.

But before you dive too deeply into writing a lot of getters and setters you should be aware that the pythonic way is to not use them. Or, if additional logic is required, to use the @property decorator.

class LibaryItem:
    def __init__(self, title, author, itemid):  # initialiser method
        self.title = title
        self.author = author
        self.itemid = itemid
        self._onloan = False
        self.duedate = datetime.date.today()

    @property
    def onloan(self):
        return self._onloan

    @onloan.setter
    def onloan(self, value):
        if value:
            self.duedate += datetime.timedelta(weeks = 3)
        self._onloan = value

    def __str__(self):
        return "%s; %s; %s; %s; %s" % (self.title, self.author, self.itemid, self.onloan, self.duedate)

class Book(LibaryItem):
    def __init__(self, title, author, itemid):
        LibaryItem.__init__(self, title, author, itemid) 
        self.requested = False
        self.requestby = 0

and then

ThisBook = Book('Title', 'Author', 'ItemID')
print(ThisBook.requested)
ThisBook.requested = True
ThisBook.onloan = True
print(ThisBook.duedate)

Upvotes: 2

MK.
MK.

Reputation: 34527

You can't access a field with 2 underscores prefix like that (see What is the meaning of a single- and a double-underscore before an object name?). You need to write a proper setter:

def SetIsRequested(self, val):
    self.__IsRequested = val

What you are experiencing is the typical silliness of dynamic languages. A field on class can be set w/o being declared and the interpreter can't help you by pointing out that you've just created a new field called "IsRequested" in your class. Saves you some typing but costs you in ability of your interpreter and IDE to prevent you from messing up.

Upvotes: 1

Related Questions