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



>我有2个类:Vehicle & Car。

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

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. 将导入移动到模块的末尾

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

更新:我得到了一些评论,解释说这可能是循环导入的问题,并且有 2 个解决方案:

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

这里有几点错误:

  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消耗负载系数状态是有意义的。

最新更新