首页 > 解决方案 > 将 JSON 转储解码为对象

问题描述

我正在做我的大学作业,我的讲座正在寻找的一件事是编码一个对象并将其转储为 JSON,对其进行解码然后将其加载到PassengerFlight课堂中。

当我运行代码时,它一直显示

“PassengerFlight”对象没有属性“airlineName”

当我解码它时,VSCode 显示它具有所有设置的函数变量。我可以让它运行的唯一类是Flight删除抽象方法时的类。有什么方法可以在PassengerFlight类中运行它而不显示上述错误?

from abc import ABC, abstractmethod
import json
from json import JSONEncoder


class Flight(ABC, object):  # Flight Class (MAIN)
    def __init__(self, airlineName, departureAirport, arrivalAirport):  # Constructor Method
        self.airlineName: str  # Declaring attributes & Setting Types
        self.departureAirport: str  # Declaring attributes & Setting Types
        self.arrivalAirport: str  # Declaring attributes & Setting Types

    def setAirlineName(self, airlineName):  # Mutator Method
        self.airlineName = airlineName

    @abstractmethod  # Marking this methods as abstract method, any concrete subclass will have to implement this method
    def getPrice(self):
        pass

    def setDepartureAirport(self, departureAirport):  # Mutator Method
        self.departureAirport = departureAirport

    def getDepartureAirport(self):  # Accessor Method
        if len(self.departureAirport) > 0:  # Error Checking
            return self.departureAirport
        else:
            return "No departure airport set"

    def setArrivalAirport(self, arrivalAirport):  # Mutator Method
        self.arrivalAirport = arrivalAirport

    def getArrivalAirport(self):  # Accessor Method
        if len(self.arrivalAirport) > 0:  # Error Checking
            return self.arrivalAirport
        else:
            return "No arrival airport set"

    def __eq__(self, otherFlight):
        return (self.airlineName == otherFlight.airlineName)

    def __str__(self):  # Overiding Method
        return "\n==================================================\n++++++++++++++++++ Flight Info ++++++++++++++++++\n==================================================\nAirline Name: " + self.airlineName + "\Departure Airport: " + self.departureAirport + "\nArrival Airport: " + self.arrivalAirport


class PassengerFlight(Flight, object):  # PassengerFlight Class (EXTENDS MAIN)
    def __init__(self, airlineName, departureAirport, arrivalAirport, price, redEye, passengerList, flightType, baggageWeight):  # Constructor Method
        super().__init__(airlineName, departureAirport, arrivalAirport)
        self.passengerList: list  # Declaring attributes & Setting Types
        self.flightType: str  # Declaring attributes & Setting Types
        self.baggageWeight: float  # Declaring attributes & Setting Types
        self.price: float  # Declaring attributes & Setting Types
        self.redEye: bool

    def getAirlineName(self):  # Accessor Method
        if len(self.airlineName) > 0:  # Error Checking
            return self.airlineName
        else:
            return "No airline name set"

    def setRedEye(self, redEye):
        self.redEye = redEye

    def isRedEye(self):
        if self.redEye == True:
            return "Flight is red eye"
        else:
            return "Flight is not a red eye"

    def setPassengerName(self, passengerList):  # Mutator Method
        self.passengerList = passengerList

    def getPassengerName(self):  # Accessor Method
        if len(self.passengerList) > 0:  # Error Checking
            self.passengerList.sort()
            return self.passengerList
        else:
            return "Passenger List Not Set"

    def setFlightType(self, flightType):  # Mutator Method
        self.flightType = flightType

    def getFlightType(self):  # Accessor Method
        if len(self.flightType) > 0:  # Error Checking
            return self.flightType
        else:
            return "No Flight Type Set"

    def setBaggageWeight(self):  # Mutator Method
        baggageWeight = 0
        for i in range(len(self.passengerList)):  # Iterates through passenger list
            baggageWeight += 50.00  # For each passenger in the list add 50KG to baggage variable
        self.baggageWeight = baggageWeight  # Set our attribute equal to the variable

    def getBaggageWeight(self):  # Accessor Method
        if self.baggageWeight == 0:
            return "No Baggage Weight Set"
        else:
            return self.baggageWeight

    def setPrice(self, price):
        self.price = price * len(self.passengerList)

    def getPrice(self):
        if self.price != 0:
            return self.price
        else:
            return "Price is not set"

    def sortedNames(self):
        return sorted(self.passengerList)

    def __str__(self):  # Overiding Method
        return super().__str__() + "\nPassenger Names using sort(): " + str(self.getPassengerName()) + "\nFlight Type: " + self.flightType + "\nBaggage Weight: " + str(self.baggageWeight) + '(KG)\n' + "Money earned for this flight is: " + str(self.getPrice()) + "\nPassenger Names using Sorted(): " + str(self.sortedNames()) + '\n==================================================\n'

class FlightEncoder(JSONEncoder):
    def default(self, o):
        return o.__dict__


##########################################################
#           Calling PassengerFlight Class           #
##########################################################
# Initialize Class & Set to Variable
passenger = PassengerFlight(None, None, None, None, None, None, None, None)
passenger.setAirlineName('Aer Lingus')  # Set mutators & values
passenger.setArrivalAirport('Chicago O\'Hare Intl')  # Set mutators & values
passenger.setDepartureAirport('Dublin')  # Set mutators & values
passenger.setRedEye(True)
passenger.setFlightType('Long Haul')  # Set mutators & values
passenger.setPassengerName(
    ['Andrew Check', 'Graham Whitaker', 'John Eire', 'Vicky Bunsworth', 'Lorna Lopsworth'])  # Set mutators & values
passenger.setBaggageWeight()  # Set mutators & values
passenger.setPrice(200.00)
# uses the overridden _str_ method to print detail of the class
print(passenger)
##########################################################
passengerEncode = json.dumps(passenger, cls=FlightEncoder, indent=4)
passengerDecode = json.loads(passengerEncode)
passengerObj = PassengerFlight(**passengerDecode)
print(passengerObj)

标签: pythonpython-3.xoop

解决方案


暗示

def __str__(self):  # Overiding Method
    return (
        super().__str__()
        + "\nPassenger Names using sort(): "
        + str(self.getPassengerName())
        + "\nFlight Type: "
        + self.flightType
        + "\nBaggage Weight: "
        + str(self.baggageWeight)
        + "(KG)\n"
        + "Money earned for this flight is: "
        + str(self.getPrice())
        + "\nPassenger Names using Sorted(): "
        + str(self.sortedNames())
        + "\n==================================================\n"
    )

你打电话super().__str__()selfPassengerFlight从 继承的实例Flightsuper()意思是:“调用父类中定义的方法next in__mro__ ”。Flight没有属性。


极好的

super()函数用于访问父类或兄弟类的方法和属性。该super()函数返回一个表示父类的对象。

面向对象

在父类中使用子类属性打破了“依赖倒置原则”(SOLID)。

在面向对象设计中,依赖倒置原则是解耦软件模块的一种特定形式。当遵循这一原则时,从高级策略设置模块到低级依赖模块建立的常规依赖关系被颠倒,从而使高级模块独立于低级模块实现细节。

高级模块不应该依赖于低级模块。两者都应该依赖于抽象(例如,接口)。抽象不应该依赖于细节。细节(具体实现)应该依赖于抽象。

您的抽象取决于更高级别的实现。

解决方案

from abc import ABCMeta, abstractproperty


class Flight(metaclass=ABCMeta):
    @abstractproperty
    def airLineName(self):
        raise NotImplementedError()

使用抽象中声明的属性,您必须在子类型中实现它。基于此,您可以在没有错误和风险的情况下使用抽象中的抽象属性来调用未实现的属性。此外,它满足 SOLID 原则。


推荐阅读