Python - Классы и основы ООП

Я не до конца понимаю занятия. Я прочитал документацию по Python и несколько других руководств. Я понимаю основную суть этого, но не понимаю нюансов. Например, в моем коде здесь:

class whiteroom():
    """ Pick a door: red, blue, green, or black. """

    do = raw_input("> ")

    if "red" in do:
        print "You entered the red room."

    elif "blue" in do:
        print "You entered the blue room."

    elif "green" in do:
        print "You entered the green room."

    elif "black" in do:
        print "You entered the black room."

    else:
        print "You sit patiently but slowly begin to stave.  You're running out of time."
        return whiteroom()

game = whiteroom()
game

(оригинальный кодпад)

Я хотел бы вернуть класс whiteroom. Что либо невозможно, либо сделано неправильно. Если бы вы могли выяснить, как вернуть класс или как "связать" два класса вместе, чтобы whiteroom повторялся в else, а другие комнаты (которые были бы классами) возвращались при вызове, это было бы здорово.

Кроме того, я очень шаткий на __init__ и до сих пор не совсем уверен, какова его цель. Все продолжают говорить мне, что это "инициализирует", что я уверен, что это делает, но это, кажется, не помогает моему мозгу.

Ответ 1

Функции сильно отличаются от классов. Похоже, вы взяли функцию и только что изменили def на class. Я предполагаю, что в основном работает в вашем случае, но это не то, как должны идти классы.

Классы содержат функции (методы) и данные. Например, у вас есть мяч:

class Ball(object):
    # __init__ is a special method called whenever you try to make
    # an instance of a class. As you heard, it initializes the object.
    # Here, we'll initialize some of the data.
    def __init__(self):
        # Let add some data to the [instance of the] class.
        self.position = (100, 100)
        self.velocity = (0, 0)

    # We can also add our own functions. When our ball bounces,
    # its vertical velocity will be negated. (no gravity here!)
    def bounce(self):
        self.velocity = (self.velocity[0], -self.velocity[1])

Теперь мы имеем класс Ball. Как мы можем его использовать?

>>> ball1 = Ball()
>>> ball1
<Ball object at ...>

Это не очень полезно. Данные там, где это может быть полезно:

>>> ball1.position
(100, 100)
>>> ball1.velocity
(0, 0)
>>> ball1.position = (200, 100)
>>> ball1.position
(200, 100)

Хорошо, круто, но какое преимущество перед глобальной переменной? Если у вас есть другой экземпляр Ball, он останется независимым:

>>> ball2 = Ball()
>>> ball2.velocity = (5, 10)
>>> ball2.position
(100, 100)
>>> ball2.velocity
(5, 10)

И ball1 остается независимым:

>>> ball1.velocity
(0, 0)

Теперь как насчет этого метода bounce (функция в классе) мы определили?

>>> ball2.bounce()
>>> ball2.velocity
(5, -10)

Метод bounce заставил его изменить данные velocity. Опять же, ball1 не был затронут:

>>> ball1.velocity

Применение

Мяч аккуратный и все, но большинство людей не имитирует это. Вы делаете игру. Подумайте, какие у нас есть вещи:

  • Комната - самая очевидная вещь, которую мы могли бы иметь.

Так что сделай комнату. Номера имеют имена, поэтому у нас есть некоторые данные для хранения:

class Room(object):
    # Note that we're taking an argument besides self, here.
    def __init__(self, name):
        self.name = name  # Set the room name to the name we got.

И дайте ему экземпляр:

>>> white_room = Room("White Room")
>>> white_room.name
'White Room'

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

Подумайте о том, что мы хотим делать с комнатами:

Мы хотим взаимодействовать с комнатами.

И как мы это делаем?

Пользователь вводит текст, на который отвечает.

Как он ответил, зависит от комнаты, поэтому позвольте сделать ручку комнаты с помощью метода interact:

class WhiteRoom(Room):  # A white room is a kind of room.
    def __init__(self):
        # All white rooms have names of 'White Room'.
        self.name = 'White Room'

    def interact(self, line):
        if 'test' in line:
            print "'Test' to you, too!"

Теперь попробуйте взаимодействовать с ним:

>>> white_room = WhiteRoom()  # WhiteRoom __init__ doesn't take an argument (even though its superclass __init__ does; we overrode the superclass __init__)
>>> white_room.interact('test')
'Test' to you, too!

В вашем оригинальном примере показано перемещение между комнатами. Позвольте использовать глобальную переменную под названием current_room для отслеживания той комнаты, в которой мы находимся. 1 Позвольте также сделать красную комнату.

1. Здесь есть лучшие варианты помимо глобальных переменных, но я собираюсь использовать их для простоты.

class RedRoom(Room):  # A red room is also a kind of room.
    def __init__(self):
        self.name = 'Red Room'

    def interact(self, line):
        global current_room, white_room
        if 'white' in line:
            # We could create a new WhiteRoom, but then it
            # would lose its data (if it had any) after moving
            # out of it and into it again.
            current_room = white_room

Теперь попробуйте следующее:

>>> red_room = RedRoom()
>>> current_room = red_room
>>> current_room.name
'Red Room'
>>> current_room.interact('go to white room')
>>> current_room.name
'White Room'

Упражнение для читателя: Добавьте код в WhiteRoom interact, который позволяет вернуться в красную комнату.

Теперь, когда у нас все работает, пусть все вместе. С нашими новыми данными name во всех комнатах мы также можем отобразить текущую комнату в приглашении!

def play_game():
    global current_room
    while True:
        line = raw_input(current_room.name + '> ')
        current_room.interact(line)

Вы также можете сделать функцию reset игры:

def reset_game():
    global current_room, white_room, red_room
    white_room = WhiteRoom()
    red_room = RedRoom()
    current_room = white_room

Поместите все определения классов и эти функции в файл, и вы можете воспроизвести его в подсказке вроде этого (если они находятся в mygame.py):

>>> import mygame
>>> mygame.reset_game()
>>> mygame.play_game()
White Room> test
'Test' to you, too!
White Room> go to red room
Red Room> go to white room
White Room>

Чтобы играть в игру, просто запустив Python script, вы можете добавить это внизу:

def main():
    reset_game()
    play_game()

if __name__ == '__main__':  # If we're running as a script...
    main()

И это базовое введение в классы и как применить его к вашей ситуации.

Ответ 2

Я уверен, что вы слышали все это раньше, но я отдам ему все.

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

Ваш код выглядит так, как будто вы пытаетесь записать всю вашу программу внутри "объекта" (на самом деле у вас есть неправильно написанная функция).

Рассмотрим это вместо этого.

Подумайте о своей ментальной модели комнат, в которых есть двери для них и доски. Двери имеют цвет. Кроме того, на досках есть текст, написанный на них. Мы оставим его там, чтобы быть простым.

Для меня это предполагает 3 разных объекта - объект двери, который имеет строку для цвета, объект доски, который имеет строку для текста, и объект комнаты, который имеет дверь и доску.

Рассмотрим следующий код:

class Door(object):
    def __init__(self, color):
        self.color = color

class Whiteboard(object):
    def __init__(self, default_text=''):
        self.text = ''
        self.write_text(default_text)

    def write_text(self, text):
        self.text += text

    def erase(self):
        self.text = ''


class Room(object):
    def __init__(self, doorcolor, whiteboardtext=''):
        self.whiteboard = Whiteboard(whiteboardtext)
        self.door = Door(doorcolor)




# make a room with a red door and no text on the whiteboard
room1 = Room('red')

# make a room with a blue door and 'yeah, whiteboard' on the whiteboard
room2 = Room('blue', 'yeah, whiteboard')

# make a room with a green door
room3 = Room('green')



# now I can play around with my 'rooms' and they keep track of everything internally

print 'room 1 door color: ' + room1.door.color
print 'room 2 door color: ' + room2.door.color


# all my rooms have a door and a whiteboard, but each one is different and self contained. For example
# if I write on room 1 whiteboard, it doesn't change anything about room 3s

print 'room1 whiteboard: ' + room1.whiteboard.text
print 'room2 whiteboard: ' + room2.whiteboard.text
print 'room3 whiteboard: ' + room3.whiteboard.text

print '-- changeing room 1 whiteboard text --'

room1.whiteboard.write_text('oop is really helpful')


print 'room1 whiteboard: ' + room1.whiteboard.text
print 'room2 whiteboard: ' + room2.whiteboard.text
print 'room3 whiteboard: ' + room3.whiteboard.text

Функция init - это то, что вызывается при инициализации нового экземпляра вашего класса. В примере я делаю 3 объекта Room, каждый из которых создает объект Door and Whiteboard внутри. Параметры, передаваемые в конструктор Room(parameter1, parameter2), передаются в функции init - вы можете видеть, что я использую это, чтобы установить цвет двери и, возможно, некоторый текст на доске. Также обратите внимание, что переменные, которые "принадлежат" объектам, ссылаются на self - эта ссылка - это то, что передается как первый параметр для всех функций класса (и становится более важным позже, когда вы расширяете классы и другие более продвинутые вещи).

Ответ 3

Ну, я понял OOPS в Python из изучения Python Марка Лутца. Это всеобъемлющий источник для понимания концепций Python, особенно для написания кода Python.

Для вашей онлайн-справки мне нравятся учебники с этого сайта. Пролистайте этот пост, он поможет вам с init. ООП в Python очень легко понять и реализовать. Сначала это кажется пугающим, но после программирования некоторых базовых кодов ООП это просто. Приятного обучения..

Ответ 4

Ты действительно далеко.

Извините, что сказал, но это едва спасено.

Из того, что я могу сказать, вы хотите что-то вроде класса комнаты, например:

class Room(object):
    ''' A generic room '''
    def __init__(self):
        self.choices = None
        self.enter()
    def enter(self):
        ''' Enter the room, to be filled out in subclass '''
        pass
    def print_choices(self):
        '''You are stuck bro'''
        print "You are stuck bro"

Затем вы можете сделать определенную комнату, такую ​​как белая, например:

class Whiteroom(Room):
    ''' A white room '''
    def __init__(self):
        self.choices = ["red", "blue", "green", "black"]
        self.enter()
    def enter(self):
        print "You sit patiently, but slowly begin to starve.  You're running out of time."
    def print_choices(self):
        print "You can choose from the following rooms:"
        print self.choices

class Blackroom(Room):
    ''' A black room '''
    def enter(self):
        print "It really dark in here.  You're out of time."

class Redroom(Room):
    ''' A red room '''
    def __init__(self):
        self.choices = ["black", "blue", "green", "white"]
        self.enter()
    def enter(self):
        print "It getting hot in here.  So take off all your clothes."
    def print_choices(self):
        print "You can choose from the following rooms:"
        print self.choices

class Blueroom(Room):
    ''' A blue room '''
    def __init__(self):
        self.choices = ["black", "red", "green", "white"]
        self.enter()
    def enter(self):
        print "It nice and cool in here.  Stay awhile if you want."
    def print_choices(self):
        print "You can choose from the following rooms:"
        print self.choices

class Greenroom(Room):
    ''' A green room '''
    def __init__(self):
        self.choices = ["black", "red", "blue", "white"]
        self.enter()
    def enter(self):
        print "You won."

Тогда вы бы сделали это, чтобы запустить игру:

print "Type 'quit' to quit"
print "Type 'choices' to see what your choices are"

current_room = Whiteroom()
done = False
while (not done):
    entry = raw_input("> ")
    if entry == "quit":
        done = True
    if "choices" in entry:
        current_room.print_choices()
    if current_room.choices:
        if entry in current_room.choices:    
            if "white" in entry:
                current_room = Whiteroom()

            if "black" in entry:
                current_room = Blackroom()

            if "red" in entry:
                current_room = Redroom()

            if "green" in entry:
                current_room = Greenroom()
                done = True

            if "blue" in entry:
                current_room = Blueroom()

Это моя лучшая попытка превратить ваш фрагмент в настоящую игру, используя классы.

Ответ 5

Объектно-ориентированное программирование может быть очень забавным, чтобы понять сначала, единственный способ действительно хэшировать через него - фактически потратить время, чтобы сделать много чтения и практики. Хорошее место для начала было бы здесь. http://www.voidspace.org.uk/python/articles/OOP.shtml и http://wiki.python.org/moin/BeginnersGuide/Programmers