Обмен структурами данных между двумя классами путем импорта - PullRequest
0 голосов
/ 23 сентября 2018

У меня есть 2 класса: Vehicle & Car.

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 - логика для создания автомобиля:

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 голосов
/ 23 сентября 2018

Обновление: я получил несколько комментариев, которые объясняют, что это, возможно, проблема циклического импорта, и имеет 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 потреблять состояние коэффициента загрузки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...