2013-07-01 2 views
3

Я не понимаю, как скрипт получает следующую комнату, и вообще как работают классы «Двигатель» и «Карта». Вот выдержка:Учиться Python Hard Way Упражнение 43

Class Map(object): 

    scenes = { 
     'central_corridor': CentralCorridor(), 
     'laser_weapon_armory': LaserWeaponArmory(), 
     'the_bridge': TheBridge(), 
     'escape_pod': EscapePod(), 
     'death': Death() 
    } 

    def __init__(self, start_scene): 
     self.start_scene = start_scene 

    def next_scene(self, scene_name): 
     return Map.scenes.get(scene_name) 

    def opening_scene(self): 
     return self.next_scene(self.start_scene) 

class Engine(object): 

    def __init__(self, scene_map): 
     self.scene_map = scene_map 

    def play(self): 
     current_scene = self.scene_map.opening_scene() 

     while True: 
      print "\n--------" 
      next_scene_name = current_scene.enter() 
      current_scene = self.scene_map.next_scene(next_scene_name) 

Я просто не понимаю, как работают эти порции. Я знаю, как работают объекты и атрибуты классов и объектов, а также все другие материалы ООП, но по какой-то причине эту часть кода я не получаю. В основном класс карты. Если бы кто-нибудь мог это объяснить, это было бы здорово.

Также (это может потребовать прочтения упражнения), почему требуется иметь эти два класса в любом случае? Не могли бы вы просто сделать это с помощью методов класса (т. Е. Методы без self в качестве параметра)? Тогда вы можете просто позвонить, например, CentralCorridor.enter(). Фактически, именно так я решил это, прежде чем читать ответ, и это получилось прекрасно.

Извините, мой главный вопрос - как работают классы Engine и Map. Другая вещь вторична.

Заранее благодарен!

+3

Без чтения упражнения я бы сказал, что эти классы, конечно, не * необходимы * для решения проблемы * вообще *. Это дизайнерское решение, которое кто-то сделал. Возможно, вы выбрали другой дизайн, возможно, даже тот, который вообще не связан с ООП. Дизайн может быть хорошим или плохим, лучше или хуже. Существует несколько принципов, которым вы можете следовать при разработке решения, например [* разделение проблем *] (http://en.wikipedia.org/wiki/Separation_of_concerns). –

+1

Я считаю, что это пример плохого использования классов. «Карта» может быть заменена атрибутом 'scenes'. Также ясно, что класс 'Engine' не должен быть классом. Любой класс, который имеет только '__init__' + единственный метод, представляет собой сложный способ записи функции. – Bakuriu

+0

Я не смотрел сайт, на котором происходит это упражнение, но использование класса может заключаться в создании основы, где его использование более уместно. Это, в конце концов, называется «Learn Python the Hard Way» :) –

ответ

7

Объект Map - это класс, который отображает ваши сцены. Он имеет несколько сцен, сохраненных в массиве.

scenes = { 
    'central_corridor': CentralCorridor(), 
    'laser_weapon_armory': LaserWeaponArmory(), 
    'the_bridge': TheBridge(), 
    'escape_pod': EscapePod(), 
    'death': Death() 
} 

Когда объект Карта сделана вы также дать ему вступительную сцену, как показано в конструкторе

def __init__(self, start_scene): 
    self.start_scene = start_scene 

Это создает переменную в Map под названием start_scene, содержащий ваше открытие сцены.

Кроме Map имеет 2 методы

# This one returns a scene based on its name or key in the scenes array 
def next_scene(self, scene_name): 
    return Map.scenes.get(scene_name) 


# And this one returns the opening scene which is set when you create the map. 
def opening_scene(self): 
    return self.next_scene(self.start_scene) 

Engine, кажется, контролируя сцены, когда играть и что играть.

# When creating an Engine object you give the map containing scenes to its constructor 
def __init__(self, scene_map): 
     self.scene_map = scene_map 

# The method which starts playing the scenes 
def play(self): 

    # the opening scene from the map is selected as the current scene 
    current_scene = self.scene_map.opening_scene() 

    # You loop all the scenes probably, conditions of this loop are unknown because you haven't posted it entirely. 
    while True: 
     print "\n--------" 
     # It seems the next scene name is known in the current scene 
     next_scene_name = current_scene.enter() 

     # It replaces current scene with the next scene from the map 
     current_scene = self.scene_map.next_scene(next_scene_name) 

почему необходимо иметь эти два класса так или иначе?

Это не так, если это не требуется в соответствии с вашим назначением

Как вы сказали, что это возможно сделать это без, НО есть веские причины, чтобы сделать это.

Таким образом, вы делаете 2 отдельных класса со своими обязанностями. Этот код более читабельен, когда приложение становится все больше и больше. И легко ориентироваться в приложении. Вы можете легко изменить части своего приложения и т. Д. Мой совет - продолжать практиковать и читать о ООП, вы заметите, что почему вы делаете то, что видите.

+1

'У этого есть некоторые статические сцены'. Слово« статический »- это термин искусства в ООП, что означает, что он имеет определенные коннотации, которые не относятся к тому, о чем вы говорите, и поэтому это может быть запутанным и нечувственным. – 7stud

+0

Неправильное использование терминологии, английский не является моим родным языком, и я изо всех сил пытался назвать это, не используя слово 'static'. Возможно, исправлено? Или «ранее установленный»? Почти весь мой английский содержит терминологию с моей работы. Сегодня я назвал книжный индекс 'ListView' * facepalm – Timmetje

+0

Ohhhhhhhhh ..... Он просто щелкнул. Спасибо! Я не мог обдумать его. Я думаю, что это была точка точечного обозначения над точечной нотацией. – Aristides

6

В классе карты есть словарь имен сцен, которые являются ключами и экземплярами разных классов в качестве значений. Чтобы получить один из экземпляров, вы вызываете метод, передаваемый в строке, которая является именем сцены. Затем класс Map возвращает экземпляр соответствующего класса.

Не могли бы вы просто сделать это с помощью методов класса (т. Е. Методы без самоуправления в качестве параметра.)? Тогда вы можете просто позвонить, например, CentralCorridor.enter().

Да, вы могли бы. Недостатком является то, что теперь вы жестко закодировали имена ваших классов сцены в своем коде. Если позже вы решите переписать свою программу, чтобы удалить некоторые сцены или добавить другие сцены, вам нужно изменить все места в коде, где вы жестко закодировали имена. Если вы используете класс Map, изменения должны быть внесены в словарь. Хотя вам все равно придется устранять вызовы методов, которые пытаются извлечь экземпляры классов, которые вы удалили. Или вы можете применить метод next_scene() к попыткам восстановить сцены, которые вы удалили из словаря.

Еще одно соображение с помощью методов класса: вам нужно сохранить «состояние»? Например, сколько игроков сейчас находится на сцене. И вам нужно создать несколько сцен такого типа?

+0

этот ответ отлично подходит для второй части вопроса, спасибо! – Aristides

Смежные вопросы