Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method of a superclass is not being inherited by a subclass

I'm following book about object oriented Python and I stumbled upon code that quite doesn't make sense to me:

class Property:

    def __init__(self, square_feet='', beds='', baths='', **kwargs):
        super().__init__(**kwargs)
        self.square_feet = square_feet
        self.num_bedrooms = beds
        self.num_baths = baths

    def display(self):
        print('PROPERTY DETAILS')
        print('----------------')
        print(f'square footage: {self.square_feet}')
        print(f'bedrooms: {self.num_bedrooms}')
        print(f'bathrooms: {self.baths}')
        print()

    def prompt_init():
        return dict(square_feet=input('Enter the square feet: '),
                beds=input('bedrooms: '), baths=input('baths: '))

    def get_valid_input(input_string, valid_options):
        input_string += ' ({}) '.format(', '.join(valid_options))
        response = input(input_string)
        while response.lower() not in valid_options:
            response = input(input_string)
        return response

    prompt_init = staticmethod(prompt_init)

then I have:

class House(Property):
    valid_garage = ('attached', 'detached', 'none')
    valid_fenced = ('yes', 'no')

    def __init__(self, num_stories='', garage='', fenced='', **kwargs):
        super().__init__(**kwargs)
        self.garage = garage
        self.fenced = fenced
        self.num_stories = num_stories

    def display(self):
        super().display()
        print('HOUSE DETAILS')
        print(f'# of stories: {self.num_stories}')
        print(f'garage: {self.garage}')
        print(f'fenced yard: {self.fenced}')

    def prompt_init():
        parent_init = Property.prompt_init()
    --> fenced = get_valid_input('Is the yard fenced ? ',   House.valid_fenced)
        garage = get_valid_input('Is there a garage ? ', House.valid_garage)
        num_stories = input('How many stories ? ')

        parent_init.update({
            'fenced': fenced,
            'garage': garage,
            'num_stories': num_stories
        })
        return parent_init
        prompt_init = staticmethod(prompt_init)


class Rental:

    def __init__(self, furnished='', utilities='', rent='', **kwargs):
        super().__init__(**kwargs)
        self.furnished = furnished
        self.utilities = utilities
        self.rent = rent

    def display(self):
        super().display()
        print('RENTAL DETAILS')
        print(f'rent: {self.rent}')
        print(f'estimated utilities: {self.utilities}')
        print(f'furnished: {self.furnished}')

    def prompt_init():
        return dict(
            rent=input('What is the monthly rent ? '), utilities=input('What are the estimated utilities ? '),
            furnished=input('Is the property furnished ? ', ('yes', 'no')))
    prompt_init = staticmethod(prompt_init)


class HouseRental(Rental, House):

    def prompt_init():
        init = House.prompt_init()
        init.update(Rental.prompt_init())
        return init
    prompt_init = staticmethod(prompt_ini

when I instantiate HouseRental class like this:

init = HouseRental.prompt_init()

I'm getting bunch of prompts as expected but I'm also getting error

get_valid_input not defined

on the line I marked with -->, Which doesn't make sense to me because the method is defined in Property superclass and House class is a subclass of Property which inherits all methods Property have.

How come House class isn't recognizing the method?

like image 287
Dan Cohen Avatar asked Dec 06 '25 04:12

Dan Cohen


1 Answers

Pass self as the first argument to your prompt_init method in House, and call the inherited method with self.get_valid_inputs(...).

In your House class:

def prompt_init(self):
    parent_init = Property.prompt_init()
    fenced = self.get_valid_input('Is the yard fenced ? ',   House.valid_fenced)
    garage = self.get_valid_input('Is there a garage ? ', House.valid_garage)
    num_stories = input('How many stories ? ')
    # ...

You also have to pass self as the first argument of the parent class's get_valid_input method. This is because Python automatically passes a reference to the calling object as the first argument to class methods, so if you do not account for that in your signature, you will get "too many arguments" errors.

In your Property class:

def get_valid_input(self, input_string, valid_options):
    input_string += ' ({}) '.format(', '.join(valid_options))
    response = input(input_string)
    # ...

Then house = House().prompt_init() ran without errors for me.

It looks like you might need to add self as an argument to all of your other prompt_init methods for your subclasses. Generally you should always pass self as the first argument to methods in a class.

like image 70
Engineero Avatar answered Dec 08 '25 16:12

Engineero