子类未继承超类的方法

时间:2019-05-07 20:42:05

标签: python python-3.x oop

我正在关注有关面向对象的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类是{{1}的子类},它将继承Property拥有的所有方法。

Property类为什么无法识别该方法?

2 个答案:

答案 0 :(得分:1)

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班上:

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作为类中方法的第一个参数传递。

答案 1 :(得分:0)

对我有用的是将方法从超类中移出并留给它 在这样的全球范围内:

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)