DMarlon Studio

Lección 8 · 8 de 20

Clases y objetos · Python

Programación orientada a objetos en Python: clases, __init__, self, atributos, métodos, propiedades y __str__, con jugadores de un juego de rol.

Python · Clases y objetos en DMarlon Studio: el código del ejemplo y su salida en la terminal

Una clase es un molde y cada objeto (o instancia) es una pieza hecha con él. Player("Aria", attack=35) crea un jugador nuevo: Python reserva el objeto y llama a `__init__`, que rellena sus datos.

El primer parámetro de cada método, `self`, es el propio objeto. self.name = name crea un atributo de instancia: cada jugador tiene el suyo. max_health, en cambio, se escribe en el cuerpo de la clase y es un atributo de clase, compartido por todos (Player.max_health).

Los métodos son funciones que trabajan con el objeto. hit(self, other) recibe a otro jugador y le resta vida sin bajar de cero con max(0, ...); pick_up añade objetos a la lista inventory, que también es propia de cada jugador porque se crea en __init__.

@property convierte alive en un valor calculado que se lee como un atributo, sin paréntesis: while orc.alive: repite los golpes hasta que el orco se queda sin vida. __str__ decide cómo se ve el objeto en print().

La última línea distingue dos ideas: hero y orc son del mismo tipo (type(hero) is type(orc)), pero son objetos distintos (hero is orc es False).

Código · main.py

class Player:    """A player in a small role-playing game."""    max_health = 100                  # class attribute: shared by all    def __init__(self, name, attack):        self.name = name              # instance attributes: one per object        self.attack = attack        self.health = Player.max_health        self.inventory = []    def hit(self, other):        other.health = max(0, other.health - self.attack)        print(f"{self.name} hits {other.name}: {other.health} HP left")    def pick_up(self, item):        self.inventory.append(item)    @property    def alive(self):                  # used like an attribute, no ()        return self.health > 0    def __str__(self):        return f"{self.name} ({self.health}/{self.max_health} HP)"hero = Player("Aria", attack=35)orc = Player("Grok", attack=20)hero.pick_up("potion")while orc.alive:    hero.hit(orc)print(hero, "| inventory:", hero.inventory)print(orc, "| alive:", orc.alive)print("Same class:", type(hero) is type(orc), "| same object:", hero is orc)

Salida · python3 main.py

Aria hits Grok: 65 HP left
Aria hits Grok: 30 HP left
Aria hits Grok: 0 HP left
Aria (100/100 HP) | inventory: ['potion']
Grok (0/100 HP) | alive: False
Same class: True | same object: False

Para recordar

  • class define el molde; Clase(...) crea un objeto.
  • __init__ prepara cada objeto nuevo; self es ese objeto.
  • Los atributos de self son de cada objeto; los del cuerpo de la clase, de todos.
  • @property expone un cálculo como si fuera un atributo.
  • __str__ controla lo que escribe print().

Ejercicio

Añada un método heal(amount) que suba la vida sin pasar de max_health y haga que Grok se cure 20 puntos después del segundo golpe.