Objetos

Me perdí con los nombres. ¿Qué es una clase, un objeto, un método y un atributo?

Recomendamos leer la unidad 14 del apunte teórico, pero en líneas generales:

  • Una clase es la definición de un tipo de dato, el cuál contiene atributos y métodos.
  • Un objeto es una instancia de una clase. Tiene su propio estado y un comportamiento definido por la clase. Se puede pensar a la clase como una plantilla o molde que permite crear múltiples objetos.
  • Un método es una operación particular del objeto definida por la clase. Serían las funciones asociadas al objeto.
  • Un atributo es un dato particular del objeto definida por la clase. Serían las variables asociadas al objeto.

¿Qué puedo definir como atributo de una clase?

¡Cualquier tipo de dato! Esto incluye tipos de datos simples, secuencias o incluso otros objetos.

Tampoco es necesario que el valor inicial de los atributos sea parámetro del constructor. Se puede asignar un valor fijo en el constructor

class Conductor:
    def __init__(self, nombre, apellido):
        self.nombre = nombre
        self.apellido = apellido


class Colectivo:

    def __init__(self, numero_linea, conductor):
        self.numero_linea = numero_linea
        self.conductor = conductor
        self.pasajeros = []

conductor = Conductor("John", "Doe")
colectivo = Colectivo("152", conductor)

¿Qué es composición de objetos?

Se trata de objetos que tienen otros objetos dentro de este. El código de la pregunta anterior incluye una composición, porque el Colectivo tiene un objeto del tipo Conductor.

En la sección 14.5 del apunte teórico hay otro ejemplo.

Tengo un atributo o método de uso interno y no quiero que se llame o acceda de afuera!

Pensando en el caso "Alan escribe una clase X" y "Bárbara utiliza la clase X en su código", Alan podría escribir atributos o métodos que no deberían ser accedidos por Bárbara.

Estos atributos o métodos deberían definirse como privados, para que Bárbara no pueda acceder a ellos. Python no tiene forma de definir nombres privados pero existe una convención: todo atributo o método que comience con _ en su nombre no debe ser accedido por Bárbara.

class Rectangulo:

    def __init__(self, x1, y1, x2, y2):
        self._p1 = Punto(x1, y1)
        self._p2 = Punto(x2, y2)

No puedo copiar mi objeto / Mi objeto se modifica y no sé por qué!

Los objetos en Python son mutables, entonces se deben aplicar las mismas precauciones que los otros tipos de datos mutables como las listas y los diccionarios.

Una asignación de una variable a otra con = haría que ambas compartan la referencia a un mismo objeto.

En la sección 14.6 del apunte teórico entra en detalle sobre el tema.

Veo el error '' object is not callable

Esto sucede cuando un atributo tiene el mismo nombre que un método. Tomando por ejemplo el siguiente código, al ejecutarse se lanza la excepción:

class Punto:
    def __init__(self, x, y):
        self.coord_x = x
        self.coord_y = y

    def coord_x(self):
        return coord_x

p = Punto(2, 3)
print(p.coord_x())

Una vez creado el objeto, el __init__ sobreescribe la referencia self.coord_x de tal forma que apunta a un entero en vez del método coord_x. Para arreglar este problema debe tomarse un nombre diferente para el método y el atributo.