2014-01-08 1 views
0

актуальная проблема я столкнулся намного сложнее, чем это, но это довольно много, что она сводится к:Дизайн недостаток - Пытаясь предотвратить перекрестное импорт

World.py

import Cell 

worldobjects = [] 

for i in range(10): #create a bunch of initial cells 
    worldobjects.append(Cell.Cell()) 

while True: 
    for obj in worldobjects: 
     obj.update() 

Cell.py

from World import worldobjects #This is the problem, python does not like cross imports 

class Cell: 
    def __init__(self): 
     self.lifetime = 0 #Keep track of frames spent 'alive' 

    def update(self): 
     self.lifetime += 1 
     if self.lifetime > 30: 
      worldobjects.append(Cell()) #Add a new cell to the world 
      self.lifetime = 0 #Reset lifetime 

ошибка, которая немного неспецифичны, но я знаю, что это означает, что я не должен быть кросс-импортирования материал:

ImportError: No module named worldobjects 

Я знаю, что это недостаток дизайна, но я не совсем уверен, как я мог бы работать по-другому. Как видно из кода, каждая ячейка должна «воспроизводить» каждые 30 кадров, и единственный способ, которым это возможно, - добавить их в массив в файле World.py. Я рассматривал перемещение массива worldobjects в свой собственный файл, но для меня это немного грязно. Любой, кто мог бы помочь мне с этой проблемой?

+0

Спасибо! Я забыл об этом и так же, как я его исправил. Kara исправил его для меня :-) – Flubber

+0

Мое общее понимание заключается в том, что плохая форма имеет что-либо вне класса или функции, если вы планируете импортировать какой-то код.Поместите код, который создает '' 'worldobjects''' в функцию, затем вызовите эту функцию в Cell.py – wnnmaw

+0

@wnnmaw Я понимаю, что это плохая форма, но она дала мне наименьшую головную боль при работе с Python и ее (в мое мнение) путают систему импорта. Что касается вашего решения, я предполагаю, что мне все равно придется импортировать функцию-создатель из World.py, что оставляет мне ту же проблему, что и сейчас. Или я неверно истолковал ваш ответ? – Flubber

ответ

1

Это хороший пример того, почему глобальные переменные являются плохая идея. Вместо того, чтобы ячейки нуждались в знаниях о существовании глобального объекта worldobjects, было бы лучше рассказать каждой ячейке об этой переменной, когда она будет создана. Например, вы можете передать ссылку на это в конструкторе. Или создайте новую функцию, которая инкапсулирует как создание новой ячейки, так и рассказ об объектах мира.

Или вы можете полностью переместить логику проверки на всю жизнь из ячейки и поместить это в мировое обновление. Это на самом деле имеет больше смысла для меня, поскольку у меня не было бы каждой ячейки, ответственной за создание новых ячеек.

+0

Я просто собираюсь бросить свое второе решение, я думаю, что я слишком стараюсь понять концепцию ООП, и это просто казалось логичным мне, чтобы каждая клетка заботилась о себе. Спасибо! – Flubber

+0

Отъезд [эта книга] (http://www.amazon.com/Head-First-Object-Oriented-Analysis-Design/dp/0596008678). У этого есть действительно простой подход, чтобы передать идеи и как-то заставляет их придерживаться. – LavaScornedOven

2

Что о сохранении ссылки на WorldObjects в камере:

Cell.py

#from World import worldobjects #This is the problem, python does not like cross imports 

class Cell: 
    def __init__(self, worldobjects): 
     self.lifetime = 0 #Keep track of frames spent 'alive' 
     self.worldobjects = worldobjects 

    def update(self): 
     self.lifetime += 1 
     if self.lifetime > 30: 
      self.worldobjects.append(Cell(self.worldobjects)) #Add a new cell to the world 
      self.lifetime = 0 #Reset lifetime 

World.py

import Cell 

worldobjects = [] 

for i in range(10): #create a bunch of initial cells 
    worldobjects.append(Cell.Cell(worldobjects)) 

while True: 
    for obj in worldobjects: 
     obj.update() 
0

Хотя я согласен с @RickyA по этому вопросу и всем остальным комментариям о дизайне предоставленного образца, я столкнулся с аналогичными проблемами с контейнерами Flask и WSGI, для которых требуются глобальные (по крайней мере, объект приложения), поэтому дополнительная бдительность в отношении требуется круговой импорт. Это ничего из космоса, но это неприятно.

Возможно, следующий подход поможет кому-то с аналогичными проблемами (включая сам плакат). Таким образом, одна из возможностей заключается в извлечении глобалов в отдельный файл, который служит в качестве промежуточного посредника импорта. Он не может решить каждую проблему в классе круговых импортов, но довольно прост в случаях, когда он применим.

Cell.py

import WorldObjects 

class Cell: 
    def __init__(self): 
     self.lifetime = 0 #Keep track of frames spent 'alive' 

    def update(self): 

     self.lifetime += 1 
     if self.lifetime > 30: 
      WorldObjects.objects.append(Cell()) #Add a new cell to the world 
      self.lifetime = 0 #Reset lifetime 

World.py

import Cell 
import WorldObjects 

for i in range(10): #create a bunch of initial cells 
    WorldObjects.objects.append(Cell.Cell()) 

while True: 
    for obj in WorldObjects.objects: 
     obj.update() 

WorldObjects.py

objects = [] 
Смежные вопросы