继承没有属性?

时间:2014-12-08 06:27:50

标签: python inheritance python-3.x

class Airplane:

    def __init__(self, plane_model, serial_num, num_seats, miles_travelled):
        self.model = plane_model
        self.serial = serial_num
        self.seat = num_seats
        self.miles = miles_travelled

class Flight:

    def __init__(self, plane):
        self.passangers = []
        self.airplane = plane

我正在尝试完成以下功能:

    def add(self, passenger):
        """(Flight, str) -> bool

        If there are still seats avalaible on this flight, add passenger to the passenger list.       
        Return true iff passenger is added to this flight.

        >>> a = Airplane('Cesna 150E', '9378', 1, 824.8)
        >>> f = Flight(a)
        >>> f.add('Myrto') # Decreases the seat by 1
        True
        >>> f.add('Jen') # No more seats avalaible
        False
        """

到目前为止,我的尝试:

        if self.seat > 0:
            self.seat -= 1 #num_seats
            return True
        else:
            return False

当然,如果添加乘客,实例变量num_seats自然会减少1。可用座位数显示在Airplane类的第三个参数上。

如果我使用我设计的函数,尝试完全相同的操作(如docstring中的操作)会返回以下错误:

Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    f.add('a')
  File "/Users/N/Desktop/Untitled.py", line 39, in add
    if self.seat > 0:
AttributeError: 'Flight' object has no attribute 'seat'

我想我可能会遗漏一些东西,但我不确定它是什么。

1 个答案:

答案 0 :(得分:1)

您的具体错误是Flight实例没有seat属性,这是Airplane实例的属性,因此应通过self.airplane访问attribute(提供将用于Airplane实例的Flight实例的链接):

if self.airplane.seat > 0:
      # ^ access via 'airplane' attribute

但是,我认为你的建模一般略有偏差。添加乘客会更改Flight实例上的免费座位数,但不会更改Airplane实例上的座位数(据我所知,当人们预订时,他们不会开始从飞机上剥离座位!)此外,旅行的距离是飞行的属性,而不是飞机。考虑到这一点,我将实现为:

class Airplane(object):

    def __init__(self, model, seats):
        self.model = model
        self.seats = seats


class Flight(object):

    def __init__(self, plane, code, distance):
        self.plane = plane
        self.code = code
        self.distance = distance
        self.passengers = []

    @property
    def free_seats(self):
        return self.plane.seats - len(self.passengers)

    def add(self, passenger):
        if not self.free_seats:
            raise Exception("Flight full.")
        self.passengers.append(passenger)   

请注意,Flight.add会检查以确保当前passengers列表符合plane.seats。无需保留单独的属性 - free_seats可以从其他属性计算,因此我将其设为只读property。使用中:

>>> f = Flight(Airplane("747", 5), "BA0123", 123)
>>> for person in ['John Cleese', 'Terry Gilliam', 'Eric Idle', 'Terry Jones', 'Michael Palin']:
    f.add(person)


>>> f.passengers
['John Cleese', 'Terry Gilliam', 'Eric Idle', 'Terry Jones', 'Michael Palin']
>>> f.add('Graham Chapman')

Traceback (most recent call last):
  File "<pyshell#32>", line 1, in <module>
    f.add('Graham Chapman')
  File "<pyshell#25>", line 13, in add
    raise Exception("Flight full.")
Exception: Flight full.
>>> f.free_seats
0

(别担心,格雷厄姆过去一直关心这一点。)

这不符合您的规格,因为如果航班已满,Flight.add现在会引发错误,而不是返回False。这是一种更加Pythonic的编码方式;见"Easier to ask for forgiveness than permission"