理解基类的super()

时间:2017-12-07 06:32:26

标签: python oop

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("square footage: {}".format(self.square_feet))
        print("bedrooms: {}".format(self.num_bedrooms))
        print("bathrooms: {}".format(self.num_baths))
        print()
    @staticmethod
    def prompt_init():
        return dict(square_feet=input("Enter the square feet: "),
            beds=input("Enter number of bedrooms: "),
            baths=input("Enter number of baths:"))


class Apartment(Property):
    valid_laundries = ("coin", "ensuite", "none")
    valid_balconies = ("yes", "no", "solarium")
    def __init__(self, balcony='', laundry='', **kwargs):
        super().__init__(**kwargs)
        self.balcony = balcony
        self.laundry = laundry
    def display(self):
        super().display()
        print("APARTMENT DETAILS")
        print("laundry: %s" % self.laundry)
        print("has balcony: %s" % self.balcony)
    @staticmethod
    def prompt_init():
        parent_init = Property.prompt_init()
        laundry = get_valid_input('What laundry facilities does '
        'the property have? ', Apartment.valid_laundries)
        while laundry.lower() not in \
            Apartment.valid_laundries:
            laundry = input("What laundry facilities does "
                "the property have? ({})".format(
                    ", ".join(Apartment.valid_laundries)))
        balcony = ''
        while balcony.lower() not in \
            Apartment.valid_balconies:
            balcony = input(
                "Does the property have a balcony? "
                "({})".format(
                ", ".join(Apartment.valid_balconies)))
        parent_init.update({
            "laundry": laundry,
            "balcony": balcony
        })
        return parent_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("# of stories: {}".format(self.num_stories))
        print("garage: {}".format(self.garage))
        print("fenced yard: {}".format(self.fenced))
    @staticmethod
    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


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 Purchase:
    def __init__(self, price='', taxes='', **kwargs):
        super().__init__(**kwargs)
        self.price = price
        self.taxes = taxes
    def display(self):
        super().display()
        print("PURCHASE DETAILS")
        print("selling price: {}".format(self.price))
        print("estimated taxes: {}".format(self.taxes))
        @staticmethod
        def prompt_init():
            return dict(
                price=input("What is the selling price? "),
                taxes=input("What are the estimated taxes? "))

class Rental:
    def __init__(self, furnished='', utilities='',
        rent='', **kwargs):
        super().__init__(**kwargs)
        self.furnished = furnished
        self.rent = rent
        self.utilities = utilities
    def display(self):
        super().display()
        print("RENTAL DETAILS")
        print("rent: {}".format(self.rent))
        print("estimated utilities: {}".format(
            self.utilities))
        print("furnished: {}".format(self.furnished))
    @staticmethod
    def prompt_init():
        return dict(
            rent=input("What is the monthly rent? "),
            utilities=input(
                "What are the estimated utilities? "),
            furnished = get_valid_input(
                "Is the property furnished? ",
                    ("yes", "no")))
class HouseRental(Rental, House):
    @staticmethod
    def prompt_init():
        init = House.prompt_init()
        init.update(Rental.prompt_init())
        return init


init = HouseRental.prompt_init() 
print(init)
house = HouseRental(**init) #I assume this holds the input from all the prompt_init, from class Property to class Rental.
house.display()

我的问题是超级如何与没有父类的类交互。在最后一行中,调用house.display()并且类HouseRental继承了2个类,第一个类没有父类。我看到当调用house.display()时,它首先调用Rental.display(),然后在Rental.display()中调用super()不会引发错误,但是指向下一个继承的类,House.display (),然后House.display()中的super()调用指向其父类Property。

我得到了super()如何以这种方式工作的要点,但我不完全理解为什么基类中的super()指向MRO中的下一个类而不是引发错误(类似于“没有父类可用“)

如果你有兴趣,这是house.display的输出:

{'square_feet': '1', 'beds': '2', 'baths': '3', 'fenced': 'no', 'garage': 'none', 'num_stories': '3', 'rent': '1', 'utilities': '4', 'furnished': 'no'}
PROPERTY DETAILS
================
square footage: 1
bedrooms: 2
bathrooms: 3

HOUSE DETAILS
# of stories: 3
garage: none
fenced yard: no
RENTAL DETAILS
rent: 1
estimated utilities: 4
furnished: no

1 个答案:

答案 0 :(得分:0)

Python中的所有类都隐式继承自Object类型:Python class inherits object

在班级中使用"没有超级班级来调用super().__init__"只需调用Object的构造函数。