Saltar al contenido principal
InicioAcerca de PythonAprender Python

Programación orientada a objetos (POO) en Python: Tutorial

Aborda los fundamentos de la Programación Orientada a Objetos (POO) en Python: explora las clases, los objetos, los métodos de instancia, los atributos y ¡mucho más!
Actualizado abr 2024  · 12 min leer

La programación orientada a objetos es un concepto muy utilizado para escribir aplicaciones potentes. Como científico de datos, tendrás que escribir aplicaciones para procesar los datos, entre otras cosas. En este tutorial, descubrirás los fundamentos de la programación orientada a objetos en Python. Aprenderás lo siguiente:

  • Cómo crear una clase
  • Instanciación de objetos
  • Añadir atributos a una clase
  • Definir métodos dentro de una clase
  • Pasar argumentos a los métodos
  • Cómo utilizar la programación orientada a objetos en Python para las finanzas

POO: Introducción

La programación orientada a objetos tiene algunas ventajas sobre otros patrones de diseño. El desarrollo es más rápido y económico, con una mejor mantenibilidad del software. Esto, a su vez, conduce a un software de mayor calidad, que además es extensible con nuevos métodos y atributos. Sin embargo, la curva de aprendizaje es más pronunciada. El concepto puede ser demasiado complejo para los principiantes. Computacionalmente, el software de POO es más lento y utiliza más memoria, ya que hay que escribir más líneas de código.

La programación orientada a objetos se basa en el paradigma de la programación imperativa, que utiliza declaraciones para cambiar el estado de un programa. Se centra en describir cómo debe funcionar un programa. Ejemplos de lenguajes de programación imperativos son C, C++, Java, Go, Ruby y Python. Esto contrasta con la programación declarativa, que se centra en lo que el programa informático debe realizar, sin especificar cómo. Ejemplos de ello son los lenguajes de consulta de bases de datos como SQL y XQuery, en los que sólo se le dice al ordenador qué datos consultar y de dónde, pero no cómo hacerlo.

La programación orientada a objetos utiliza el concepto de objetos y clases. Una clase puede considerarse como un "plano técnico" de los objetos. Pueden tener sus propios atributos (características que poseen), y métodos (acciones que realizan).

Ejemplo de POO

Un ejemplo de clase es la clase Dog. No pienses en un perro concreto, ni en tu propio perro. Estamos describiendo lo que un perro es y puede hacer, en general. Los perros suelen tener name y age; son atributos de instancia. Los perros también pueden bark; éste es un método.

Cuando hablas de un perro concreto, en programación tendrías un objeto: un objeto es una instanciación de una clase. Éste es el principio básico en el que se basa la programación orientada a objetos. Así, mi perro Ozzy, por ejemplo, pertenece a la clase Dog. Sus atributos son name = 'Ozzy' y age = '2'. Un perro diferente tendrá atributos diferentes.

Programación orientada a objetos en Python

¿Python está orientado a objetos?

Python es un gran lenguaje de programación que admite la programación orientada a objetos. Lo utilizarás para definir una clase con atributos y métodos, que luego llamarás. Python ofrece una serie de ventajas en comparación con otros lenguajes de programación como Java, C++ o R. Es un lenguaje dinámico con tipos de datos de alto nivel. Esto significa que el desarrollo es mucho más rápido que con Java o C++. No requiere que el programador declare tipos de variables y argumentos. Esto también hace que Python sea más fácil de entender y aprender para los principiantes, ya que su código es más legible e intuitivo.

Si eres nuevo en Python, asegúrate de echar un vistazo al curso Introducción a Python para la Ciencia de datos de DataCamp.

Cómo crear una clase

Para definir una clase en Python, puedes utilizar la palabra clave class, seguida del nombre de la clase y dos puntos. Dentro de la clase, hay que definir un método __init__ con def. Este es el inicializador que puedes utilizar después para instanciar objetos. Es similar a un constructor en Java. __init__ ¡siempre debe estar presente! Toma un argumento: self, que se refiere al objeto en sí. Dentro del método, se utiliza la palabra clave pass a partir de ahora, porque Python espera que escribas algo ahí. ¡Recuerda utilizar la sangría correcta!

class Dog:

    def __init__(self):
        pass

Nota: self en Python es equivalente a this en C++ o Java.

En este caso, tienes una clase Dog (casi vacía), pero aún no tienes ningún objeto. ¡Creemos uno!

Empieza a aprender Python gratis

Programación orientada a objetos en Python

BeginnerSkill Level
4
75.2K learners
Ahonda aún más en tus conocimientos, y aprende a crear clases y a aprovechar la herencia y el polimorfismo para reutilizar y optimizar el código.

Instanciación de objetos

Para instanciar un objeto, escribe el nombre de la clase, seguido de dos paréntesis. Puedes asignarlo a una variable para hacer un seguimiento del objeto.

ozzy = Dog()

E imprímelo:

print(ozzy)

<__main__.Dog object at 0x111f47278>

Añadir atributos a una clase

Tras imprimir ozzy, queda claro que este objeto es un perro. Pero aún no has añadido ningún atributo. Vamos a dar un nombre y una edad a la clase Dog reescribiéndola:

class Dog:

    def __init__(self, name, age):  
        self.name = name
        self.age = age

Puedes ver que la función toma ahora dos argumentos después de self: name y age. A continuación, se asignan a self.name y self.age respectivamente. Ahora puedes crear un nuevo objeto ozzy con un nombre y una edad:

ozzy = Dog("Ozzy", 2)

Para acceder a los atributos de un objeto en Python, puedes utilizar la anotación con punto. Esto se hace escribiendo el nombre del objeto, seguido de un punto y el nombre del atributo

print(ozzy.name)

print(ozzy.age)
Ozzy
2

Esto también puede combinarse en una frase más elaborada:

print(ozzy.name + " is " + str(ozzy.age) + " year(s) old.")
Ozzy is 2 year(s) old.

La función str() se utiliza aquí para convertir el atributo age, que es un número entero, en una cadena, para que puedas utilizarla en la función print().

Definir métodos en una clase

Ahora que tienes una clase Dog, tiene un nombre y una edad, de la que puedes hacer seguimiento, pero en realidad no hace nada. Aquí es donde entran en juego los métodos de instancia. Puedes reescribir la clase para incluir ahora un método bark(). Observa cómo se utiliza de nuevo la palabra clave def, así como el argumento self.

class Dog:

    def __init__(self, name, age):  
        self.name = name
        self.age = age

    def bark(self):
        print("bark bark!")

Ahora se puede llamar al método bark utilizando la anotación con puntos, después de instanciar un nuevo objeto ozzy. El método debe mostrar "bark bark!" en la pantalla. Observa los paréntesis (llaves) en .bark(). Se utilizan siempre que se llama a un método. En este caso están vacíos, ya que el método bark() no toma ningún argumento.

ozzy = Dog("Ozzy", 2)

ozzy.bark()
bark bark!

¿Recuerdas cómo imprimiste antes ozzy? El código siguiente implementa ahora esta funcionalidad en la clase Dog, con el método doginfo(). A continuación, instancias algunos objetos con diferentes propiedades, y llamas al método en ellos.

class Dog:

    def __init__(self, name, age):  
        self.name = name
        self.age = age

    def bark(self):
        print("bark bark!")

    def doginfo(self):
        print(self.name + " is " + str(self.age) + " year(s) old.")

ozzy = Dog("Ozzy", 2)
skippy = Dog("Skippy", 12)
filou = Dog("Filou", 8)

ozzy.doginfo()
skippy.doginfo()
filou.doginfo()
Ozzy is 2 year(s) old.
Skippy is 12 year(s) old.
Filou is 8 year(s) old.

Como puedes ver, puedes llamar al método doginfo() en objetos con la anotación con punto. La respuesta depende ahora del objeto Dog al que llames al método.

Como los perros envejecen, estaría bien que pudieras ajustar su edad en consecuencia. Ozzy acaba de cumplir 3 años, así que cambiémosle la edad.

ozzy.age = 3

print(ozzy.age)
3

Es tan fácil como asignar un nuevo valor al atributo. También podrías implementarlo como un método birthday() en la clase "Dog":

class Dog:

    def __init__(self, name, age):  
        self.name = name
        self.age = age

    def bark(self):
        print("bark bark!")

    def doginfo(self):
        print(self.name + " is " + str(self.age) + " year(s) old.")

    def birthday(self):
        self.age +=1

ozzy = Dog("Ozzy", 2)

print(ozzy.age)
2
ozzy.birthday()

print(ozzy.age)
3

Ahora, no necesitas cambiar manualmente la edad del perro. Siempre que sea su cumpleaños, basta con llamar al método birthday()

Pasar argumentos a los métodos

Te gustaría que nuestros perros tuvieran un compañero. Esto debería ser opcional, ya que no todos los perros son tan sociables. Echa un vistazo al método setBuddy() a continuación. Toma como argumentos self, como de costumbre, y buddy. En este caso, buddy será otro objeto Dog. Establece el atributo self.buddy en buddy, y el atributo buddy.buddy en self. Esto significa que la relación es recíproca; tú eres el colega de tu colega. En este caso, Filou será amigo de Ozzy, lo que significa que Ozzy se convierte automáticamente en amigo de Filou. También podrías establecer estos atributos manualmente en lugar de definir un método, pero eso requeriría más trabajo (escribir dos líneas de código en lugar de una) cada vez que quieras establecer un compañero. Observa que en Python no es necesario especificar de qué tipo es el argumento. Si esto fuera Java, sería obligatorio.

class Dog:

    def __init__(self, name, age):  
        self.name = name
        self.age = age

    def bark(self):
        print("bark bark!")

    def doginfo(self):
        print(self.name + " is " + str(self.age) + " year(s) old.")

    def birthday(self):
        self.age +=1

    def setBuddy(self, buddy):
        self.buddy = buddy
        buddy.buddy = self

Ahora puedes llamar al método con la anotación con punto, y pasarle otro objeto Dog. En este caso, el compañero de Ozzy será Filou:

ozzy = Dog("Ozzy", 2)
filou = Dog("Filou", 8)

ozzy.setBuddy(filou)

Si ahora quieres obtener información sobre el amigo de Ozzy, puedes utilizar la anotación con punto dos veces: Primero, para referirse al amigo de Ozzy, y una segunda vez para referirse a su atributo.

print(ozzy.buddy.name)
print(ozzy.buddy.age)
Filou
8

Observa que esto también se puede hacer para Filou.

print(filou.buddy.name)
print(filou.buddy.age)
Ozzy
2

También se puede llamar a los métodos del compañero. El argumento self que se pasa a doginfo() es ahora ozzy.buddy, que es filou.

 ozzy.buddy.doginfo()
Filou is 8 year(s) old.

Ejemplo de programación orientada a objetos en Python

Un ejemplo de dónde puede resultar útil la programación orientada a objetos en Python es nuestro tutorial Python para las finanzas: trading algorítmico. En él, explicamos cómo establecer una estrategia de negociación para una cartera de acciones. La estrategia de negociación se basa en la media móvil del precio de una acción. Si se cumple signals['short_mavg'][short_window:] > signals['long_mavg'][short_window:], se crea una señal. Esta señal es una predicción de la evolución futura del precio de la acción. En el código siguiente, verás que primero hay una inicialización, seguida del cálculo de la media móvil y la generación de la señal. Como no se trata de código orientado a objetos, es sólo un gran fragmento que se ejecuta de una vez. Observa que estamos utilizando aapl en el ejemplo, que es el teletipo de las acciones de Apple. Si quisieras hacer esto para una acción diferente, tendrías que reescribir el código.

# Initialize
short_window = 40
long_window = 100
signals = pd.DataFrame(index=aapl.index)
signals['signal'] = 0.0

# Create short simple moving average over the short window
signals['short_mavg'] = aapl['Close'].rolling(window=short_window, min_periods=1, center=False).mean()

# Create long simple moving average over the long window
signals['long_mavg'] = aapl['Close'].rolling(window=long_window, min_periods=1, center=False).mean()

# Create signals
signals['signal'][short_window:] = np.where(signals['short_mavg'][short_window:] > signals['long_mavg'][short_window:], 1.0, 0.0)   

# Generate trading orders
signals['positions'] = signals['signal'].diff()

# Print `signals`
print(signals)

En un enfoque orientado a objetos, sólo tienes que escribir una vez el código de inicialización y generación de señales. A continuación, puedes crear un nuevo objeto para cada acción sobre la que quieras calcular una estrategia, y llamar al método generate_signals() en él. Observa que el código de la POO es muy similar al código anterior, con la adición de self.

class MovingAverage():

    def __init__(self, symbol, bars, short_window, long_window):
        self.symbol = symbol
        self.bars = bars
        self.short_window = short_window
        self.long_window = long_window

    def generate_signals(self):
        signals = pd.DataFrame(index=self.bars.index)
        signals['signal'] = 0.0

        signals['short_mavg'] = bars['Close'].rolling(window=self.short_window, min_periods=1, center=False).mean()
        signals['long_mavg'] = bars['Close'].rolling(window=self.long_window, min_periods=1, center=False).mean()

        signals['signal'][self.short_window:] = np.where(signals['short_mavg'][self.short_window:] > signals['long_mavg'][self.short_window:], 1.0, 0.0)   

        signals['positions'] = signals['signal'].diff()   

        return signals

Ahora puedes simplemente instanciar un objeto, con los parámetros que quieras, y generar señales para él.

apple = MovingAverage('aapl', aapl, 40, 100)
print(apple.generate_signals())

Hacer esto para otras acciones resulta muy fácil. Sólo es cuestión de instanciar un nuevo objeto con un símbolo bursátil diferente.

microsoft = MovingAverage('msft', msft, 40, 100)
print(microsoft.generate_signals())

Programación orientada a objetos en Python Resumen

Hemos cubierto algunos de los principales conceptos de programación orientada a objetos en Python. Ahora ya sabes declarar clases y métodos, instanciar objetos, establecer sus atributos y llamar a métodos de instancia. Estas habilidades te serán útiles en tu futura carrera como científico de datos. Si quieres ampliar los conceptos clave que necesitas para seguir trabajando con Python, no dejes de consultar nuestro curso Python Intermedio para la Ciencia de datos.

Con la POO, tu código crecerá en complejidad a medida que tu programa se haga más grande. Tendrás diferentes clases, subclases, objetos, herencia, métodos de instancia y mucho más. Querrás mantener tu código correctamente estructurado y legible. Para ello, se aconseja seguir patrones de diseño. Son principios de diseño que representan un conjunto de directrices para evitar el mal diseño. Cada uno de ellos representa un problema específico que se repite a menudo en la programación orientada a objetos de Python y describe la solución a ese problema, que puede utilizarse repetidamente. Estos patrones de diseño de la POO pueden clasificarse en varias categorías: patrones de creación, patrones estructurales y patrones de comportamiento. Un ejemplo de patrón de creación es el singleton, que debe utilizarse cuando quieras asegurarte de que sólo puede crearse una instancia de una clase. Un iterador de Python, que se utiliza para recorrer en bucle todos los objetos de una colección, es un ejemplo de patrón de comportamiento.

Preguntas frecuentes sobre la POO en Python

¿Qué es la programación orientada a objetos (POO)?

La programación orientada a objetos es un paradigma de programación que se basa en el concepto de "objects", que pueden contener datos y código que manipula esos datos. En POO, los objetos se crean a partir de plantillas llamadas "classes", que definen las propiedades y el comportamiento de los objetos que crean. La programación orientada a objetos te permite crear código reutilizable y modelar los conceptos del mundo real con mayor precisión, lo que la convierte en una opción popular para muchos proyectos de software.

¿Qué son las clases y los objetos en Python?

En Python, una clase es una plantilla para crear objetos. Define las propiedades y el comportamiento de los objetos que se crean a partir de ella. Un objeto es una instancia de una clase, creada llamando a la clase como si fuera una función. El objeto contiene los datos y el comportamiento definidos por la clase, así como una identidad única.

¿Cómo defino una clase en Python?

Para definir una clase en Python, utiliza la palabra clave class, seguida del nombre de la clase y dos puntos. La definición de la clase está sangrada, y el bloque sangrado contiene las propiedades y métodos (funciones) que pertenecen a la clase.

¿Cómo se crea un objeto a partir de una clase en Python?

Para crear un objeto a partir de una clase en Python, debes llamar a la clase como si fuera una función, pasando los argumentos necesarios al constructor de la clase (el método __init__). 

Temas

Más información sobre Python

Certificación disponible

Course

Programación orientada a objetos en Python

4 hr
75.2K
Ahonda aún más en tus conocimientos, y aprende a crear clases y a aprovechar la herencia y el polimorfismo para reutilizar y optimizar el código.
See DetailsRight Arrow
Start Course
Ver másRight Arrow