Метод суперкласса не наследуется подклассом - PullRequest
3 голосов
/ 07 мая 2019

Я слежу за книгой об объектно-ориентированном Python и наткнулся на код, который для меня совершенно не имеет смысла:

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)

тогда у меня есть:

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

когдаЯ создаю HouseRental класс следующим образом:

init = HouseRental.prompt_init()

Я получаю кучу подсказок, как и ожидалось, но также получаю ошибку

get_valid_input не определено

в строке, которую я пометил -->, что не имеет смысла для меня, потому что метод определен в Property суперклассе, а House класс является подклассом Property, который наследует все методы Property есть.

Почему House класс не распознает метод?

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Передайте self в качестве первого аргумента вашего prompt_init метода в House и вызовите унаследованный метод с помощью self.get_valid_inputs(...).

В вашем House классе:

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 ? ')
    # ...

Вы также должны передать self в качестве первого аргумента метода get_valid_input родительского класса.Это потому, что Python автоматически передает ссылку на вызывающий объект в качестве первого аргумента для методов класса, поэтому, если вы не учтете это в своей подписи, вы получите ошибки «слишком много аргументов».

В вашемProperty class:

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

Тогда house = House().prompt_init() запустился без ошибок для меня.

Похоже, вам может понадобиться добавить self в качестве аргумента ко всем другим prompt_init методы для ваших подклассов.Обычно вы всегда должны передавать self в качестве первого аргумента в методы класса.

0 голосов
/ 08 мая 2019

Что мне помогло, так это вытащить метод из суперкласса и оставить его в глобальном масштабе, как это:

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


class Property:

    ...
    # other methods
    ...


class House(Property):

    ...
    # other methods
    ...

    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


class HouseRental(Rental, House):

    def prompt_init():
        init = House.prompt_init()
        init.update(Rental.prompt_init())
        return init
    prompt_init = staticmethod(prompt_init)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...