【问题标题】:Method of a superclass is not being inherited by a subclass超类的方法没有被子类继承
【发布时间】:2019-05-07 20:42:05
【问题描述】:

我正在关注有关面向对象的 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 类怎么不识别方法?

【问题讨论】:

  • 对于所有与 python 相关的问题,请始终使用通用 [python] 标签。自行决定使用特定于版本的标签。
  • 您知道,如果您在发布示例代码之前将其剥离为仅相关,您将获得更好的结果。此外,这样做通常可以让您自己弄清楚。无意冒犯。

标签: python python-3.x oop


【解决方案1】:

self 作为第一个参数传递给House 中的prompt_init 方法,并使用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 作为第一个参数传递给类中的方法。

【讨论】:

    【解决方案2】:

    对我有用的是将方法从超类中取出并留下 在这样的全局范围内:

    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)
    

    【讨论】:

    • 你试过我的答案了吗?也许全局范围对您有用,但我会仔细考虑这对您要使用的用例是否有意义。一般来说,您可能希望能够使用从类的父类继承的方法,我的回答显示了您是如何做到这一点的。
    • 您确实需要内化 Python 中“自我”的含义。拥有全局独立实用程序功能没有错。但是当缩进时,类作用域方法没有 self 来敲响各种警钟。我自己去过那里,花了我大约 3-4 个月,主要是因为当我每个班级只有 1 个实例时,它似乎有效。创建 2 个houserentals 并检查它们是否确实彼此隔离。
    猜你喜欢
    • 2023-03-23
    • 2013-10-23
    • 2016-02-09
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    相关资源
    最近更新 更多