问题描述
我有2个班级:车辆和汽车。
Vehicle Class包含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是创建Car的逻辑:
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
正在Car Class中更新。
而且,Class Vehicle正在创建一系列Car对象。
这给我一个错误:
File "/home/Testing/ClassC.py", line 1, in <module>
from ClassV import Vehicle
ImportError: cannot import name Vehicle
我四处搜寻,但确实可以找到解决此问题的方法。 解决此问题的正确方法是什么?
更新:我收到一些评论,解释这可能是循环进口的问题,有2个解决方案:
- 重构程序以避免循环导入
- 将导入移动到模块的末尾
我正在寻找有关如何执行这些操作的反馈。
1楼
更新:我收到一些评论,解释这可能是循环进口的问题,有2个解决方案:
- 重构程序以避免循环导入
- 将导入移动到模块的末尾
这里有几处错误:
-
您选择的术语令人困惑/错误。
为什么
Vehicle
类是Car
实例的容器? 我将其称为VehicleRegistry
或类似名称,以使其意图明确。 -
您有一个基本的设计缺陷,因为您违反了两个类的职责。
Car
实例应该能够孤立地站立,当我向其添加乘客时,它应该只影响该实例的内部状态, 而不应该影响Vehicle
的状态,这是易碎代码的秘诀,容易折断。 - 除非您确切知道自己在做什么,否则不要使用类级别的属性。 改变类级别属性的状态可以改变该类的所有实例的所述属性的状态,从而导致一些非常有趣和意想不到的行为。
这就是我所指的类级别的属性:
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年9月24日]:
或者,如果负载系数是Car
的属性,则将其放置在car本身的实例上并允许VehicleRegistry
使用负载系数状态是VehicleRegistry
。