通过导入在两个类之间共享数据结构

时间:2018-09-23 13:56:09

标签: python class oop

我有2个班级:车辆和汽车。

车辆类具有汽车对象和堆的字典。

ClassV.py:

from ClassC import Car
import heapq

class Vehicle:
    MapOfCars_ID = {}
    heap = [] # Stores the load factor of each car
    counter = 0

    def createCar(number, idnum):
        C = Car(number, idnum) # Create a car object
        self.MapOfCars_ID[counter] = C # Dict of Car_ID : Car Object
        self.heapq.heappush(heap, (0.0, counter)) # Heap stores load factor, Car_ID
        counter += 1

    def AssignCar():
        t = heapq.heappop(heap)
        MapOfCars_ID[t[1]].addPassenger()

ClassC.py是创建汽车的逻辑:

from ClassV import Vehicle

class Car:
    size = 0;
    occupiedSeats = 0
    carId = -1
    def __init__(size, id_number):
        self.size = size
        self.carId = id_number
        print "Created Car with size " + self.size + " and ID number "+ self.carId

    def addPassenger():
        if self.occupiedSeats < self.size:
            self.occupiedSeats += 1
            # Code below adjusts the load factor of the car in the heap when a passenger is added to the car 
            # Load factor = seat-occupied/total-seats-in-the-car
            for index, value in Vehicle.heap:
                if value[1] == self.carId:
                    Vehicle.heap[index] = heap[-1]
                    heap.pop()
                    t = (float(self.occupiedSeats/self.size), self.carId)
                    heap.append(t)
                    heapq.heapify(Vehicle.heap)
                    break
        else:
            print "Car is full!"

程序从另一个文件main.py运行:

from ClassV import Vehicle
from random import randint

def main():
    for i in range(1, 10): # Create 10 cars
        r = randint(1,6) # Maximum number of seats could be 6 in a car
        Vehicle.createCar(r, i) # <Car size, ID>
    Vehicle.AssignCar()

if __name__ == "__main__":
    main()

此程序的目的是创建10辆汽车,然后将乘客分配到占用最少的汽车。
从程序中可以明显看出,heap是车辆类的类属性,正在汽车类中更新。而且,Class Vehicle正在创建一系列Car对象。

这给了我一个错误:

File "/home/Testing/ClassC.py", line 1, in <module>
    from ClassV import Vehicle
ImportError: cannot import name Vehicle

我进行了搜索,但确实可以找到解决此问题的方法。解决此问题的正确方法是什么?

更新: 我收到一些评论,解释这可能是循环进口的问题,有2个解决方案:

  1. 重构程序以避免循环导入
  2. 将导入内容移动到模块末尾

我正在寻找有关如何执行其中任何一项的反馈。

1 个答案:

答案 0 :(得分:1)

  

更新:我收到一些评论,解释这可能是循环进口的问题,有2种解决方案:

     
      
  1. 重构程序以避免循环导入
  2.   
  3. 将导入内容移至模块末尾
  4.   

这里有些错误:

  1. 您选择的术语令人困惑/错误。为什么Vehicle类是Car实例的容器?我将其命名为VehicleRegistry或类似名称,以明确其意图。
  2. 您有一个基本的设计缺陷,因为您违反了两个类的职责。 Car的实例应该能够孤立地站立,当我向其添加乘客时,它应该只会影响该实例的内部状态,而不会 Vehicle,这是易碎代码的秘诀,容易破解。
  3. 请勿使用类级别的属性,除非您确切地知道自己在做什么。更改类级别属性的状态可以更改该类所有实例的所述属性的状态,从而导致一些非常有趣且意外的行为。

这就是我所指的类级属性:

class Person(object):
    first_name = "Bob"
    last_name = "Smith"

这些与类无关,而不是实例。

可能的解决方案:

这里有一些代码来说明我的意思:

您的addPassenger方法应仅将一名乘客添加到汽车中,然后返回是否成功,否则就什么也没有。

def add_passenger(self) -> bool:
    if self.capacity > self.number_of_passengers:
        self.capacity = self.capacity + 1
        return True
    return False

您将负载因子逻辑的更新放置在assign_car方法中,例如:

def assign_car(self):
    car_id = heapq.heappop(self.heap)
    car = self.vehicle_registry[car_id]
    result = car.add_passenger()

    if result:
        # Put your load factor update logic here ...
        print("A passenger was successfully added to: {0}".format(car.id_number))
    else:
        print("A passenger could not be added to the car.")

编辑[2018/09/24]:

或者,如果负载因子是Car的属性,则将其放置在汽车本身的实例上并允许VehicleRegistry消耗负载因子状态是有意义的。