Python – Clases y conceptos básicos de OOP

No entiendo completamente las clases. He leído la documentación de python y varios otros tutoriales. Tengo la idea básica de eso, pero no entiendo el matiz. Por ejemplo en mi código aquí:

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 

( teclado original)

Me gustaría devolver la clase whiteroom. Lo que es, o no es posible, o no se está haciendo correctamente. Si pudiera aclarar cómo devolver una clase o cómo “vincular” dos clases para que la sala blanca se repita en el otro y las otras salas (que serían clases) se devuelvan cuando se las llame, eso sería increíble.

También estoy súper inestable en __init__ y todavía no estoy realmente seguro de cuál es su propósito. Todos me siguen diciendo que se “inicializa”, lo cual estoy seguro de que sí, pero eso no parece estar ayudando a mi cerebro.

Las funciones son muy diferentes de las clases. Parece que tomaste una función y acabas de cambiar la def a class . Supongo que eso funciona principalmente en su caso, pero no es así como se supone que van las clases.

Las clases contienen funciones (métodos) y datos. Por ejemplo, tienes una bola:

 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's 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]) 

Ahora tenemos una clase de Ball . ¿Cómo podemos usarlo?

 >>> ball1 = Ball() >>> ball1  

No parece muy útil. Los datos son donde podría ser útil:

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

Bien, bien, pero ¿cuál es la ventaja sobre una variable global? Si tienes otra instancia de Ball , seguirá siendo independiente:

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

Y ball1 sigue siendo independiente:

 >>> ball1.velocity (0, 0) 

Ahora, ¿qué hay de ese método de bounce (función en una clase) que definimos?

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

El método de bounce hizo que modificara los datos de velocity de sí mismo. Una vez más, ball1 no fue tocado:

 >>> ball1.velocity 

Solicitud

Una pelota está limpia y todo, pero la mayoría de las personas no simulan eso. Estás haciendo un juego. Pensemos en qué tipo de cosas tenemos:

  • Una habitación es lo más obvio que podríamos tener.

Así que vamos a hacer una habitación. Las habitaciones tienen nombres, así que tendremos algunos datos para almacenar que:

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

Y vamos a hacer un ejemplo de ello:

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

Spiffy. Sin embargo, esto no resulta tan útil si quiere que diferentes salas tengan una funcionalidad diferente, así que hagamos una subclase . Una subclase hereda toda la funcionalidad de su superclase , pero puede agregar más funcionalidad o anular la funcionalidad de la superclase.

Pensemos en lo que queremos hacer con las habitaciones:

Queremos interactuar con las habitaciones.

¿Y cómo hacemos eso?

El usuario escribe una línea de texto a la que se responde.

La forma en que se responde depende de la sala, así que hagamos que la sala maneje eso con un método llamado 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!" 

Ahora tratemos de interactuar con él:

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

Su ejemplo original mostraba moverse entre habitaciones. Usemos una variable global llamada current_room para rastrear en qué sala estamos. 1 También hagamos una habitación roja.

1. Hay mejores opciones además de las variables globales aquí, pero voy a usar una para simplificar.

 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 

Ahora intentemos eso:

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

Ejercicio para el lector: agregue código a la interact WhiteRoom que le permita regresar a la sala roja.

Ahora que tenemos todo funcionando, juntémoslo todo. ¡Con nuestros nuevos datos de name en todas las salas, también podemos mostrar la sala actual en el indicador!

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

También es posible que desee realizar una función para restablecer el juego:

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

Coloque todas las definiciones de clase y estas funciones en un archivo y puede reproducirlas en el indicador de comandos de esta manera (asumiendo que están en 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> 

Para poder jugar el juego simplemente ejecutando el script de Python, puedes agregar esto en la parte inferior:

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

Y esa es una introducción básica a las clases y cómo aplicarla a su situación.

Estoy seguro de que has escuchado todo esto antes, pero lo intentaré.

Las clases son una forma de agrupar un grupo de funciones y variables en un solo objeto. Cuando llegas a eso, esta es simplemente una forma de organizar todo en grupos que tengan sentido. Hay beneficios en el camino para hacer que las cosas sean más fáciles de entender, depurar, extender o mantener, pero básicamente es solo una forma de hacer que algo más definido en su modelo mental.

Parece que su código está intentando escribir todo el progtwig dentro de un ‘objeto’ (en realidad, solo tiene una función escrita incorrectamente).

Considera esto en su lugar.

Piense en su modelo mental de habitaciones que tienen puertas y pizarrones en ellas. Las puertas tienen un color. Además, las pizarras blancas pueden tener algún texto escrito en ellas. Lo dejaremos allí para que sea sencillo.

Para mí, esto sugiere 3 objetos diferentes: un objeto de puerta que tiene una cadena de color, un objeto de pizarra que tiene una cadena para el texto y un objeto de sala que tiene una puerta y una pizarra.

Considere el siguiente código:

 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's 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 

La función de inicio es a lo que se llama cuando ‘inicializa’ una nueva instancia de su clase. En el ejemplo, estoy creando 3 objetos de Sala, cada uno de los cuales crea un objeto de Puerta y Pizarra blanca internamente. Los parámetros que paso en la Room(parameter1, parameter2) del constructor Room(parameter1, parameter2) se pasan a las funciones de inicio . Puede ver que estoy usando esto para configurar el color de la puerta y, opcionalmente, algo de texto en la pizarra. También tenga en cuenta que las variables que ‘pertenecen’ a los objetos están referenciadas con self : esta referencia es lo que se pasa como primer parámetro a todas las funciones de clase (y se vuelve más importante más adelante cuando extienda clases y otras cosas más avanzadas).

Bueno entendí OOPS en Python de Learning Python por Mark Lutz . Es una fuente completa para comprender los conceptos de Python, especialmente para codificar la forma Pythonic .

Para su referencia en línea, me gustan los tutoriales de este sitio. Revisa este post , te ayudará con init. Los OOP en Python son muy fáciles de entender e implementar. Parece desalentador al principio, pero es muy fácil después de progtwigr algunos códigos OOP básicos. Disfruta aprendiendo..

Estás muy lejos.

Lamento decirlo, pero esto es apenas rescatable.

Por lo que puedo decirte que quieres algo como una clase de habitación, por ejemplo:

 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" 

Entonces puedes hacer una habitación específica como la sala blanca así:

 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's 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's 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's 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." 

Entonces tendrías que hacer esto para ejecutar el juego:

 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() 

Ese es mi mejor bash de convertir tu fragmento en un juego real, usando clases.

La Progtwigción Orientada a Objetos puede ser una cosa muy divertida de comprender al principio, la única manera de realmente resolverlo es tomarse el tiempo para leer y practicar mucho. Un buen lugar para comenzar sería aquí. http://www.voidspace.org.uk/python/articles/OOP.shtml y http://wiki.python.org/moin/BeginnersGuide/Programmers