Artículo original escrito por: TK
Artículo original: Learning Python: From Zero to Hero
Traducido y adaptado por: Rafael D. Hernandez

En primer lugar, ¿qué es Python? De acuerdo con su creador, Guido van Rossum, Python es un:

"el lenguaje de programación de alto nivel, y su filosofía de diseño central, tiene que ver con la legibilidad del código y una sintaxis que permite a los programadores expresar conceptos en unas pocas líneas de código.”

Para mí, la primera razón para aprender Python fue que es, de hecho, un hermoso lenguaje de programación. Era realmente natural programar en él y expresar mis pensamientos.

Otra razón fue que podemos usar la programación en Python de múltiples maneras: en ciencia de datos, desarrollo web y aprendizaje automático brillan aquí. Quora, Pinterest y Spotify usan Python para su desarrollo web de backend. Así que vamos a aprender un poco al respecto.

Los fundamentos

1. Variables

Puedes pensar en variables como palabras que almacenan un valor. Así de simple.

En Python, es muy fácil definir una variable y establecer un valor para ella. Imagina que deseas almacenar el número 1 en una variable llamada "uno"."Hagámoslo:

uno = 1

¿Qué tan simple fue eso? Acabas de asignar el valor 1 a la variable "uno.”

dos = 2
algunos_numeros = 10000

Y puedes asignar cualquier otro valor a cualquier otra variables que desees. Como puedes ver en la tabla anterior, la variable "dos" almacena el entero 2, y "algunos_numeros" almacena 10000.

Además de enteros, también podemos usar booleanos (True / False), cadenas, flotadores y muchos otros tipos de datos.

# booleans
verdadero_booleano = True
falso_booleano = False

# cadena
mi_nombre = "Leandro Tk"

# floatante
precio_de_libro = 15.80

2. Flujo de control: sentencias condicionales

"If" utilizas una expresión para evaluar si una sentencia es True o False. Si es True, ejecuta lo que está dentro de la instrucción "if". Por ejemplo:

if True:
  print("Hola Python If")

if 2 > 1:
  print("2 es mayor que 1")

2 es mayor que 1, por lo que se ejecuta el código "print".

La sentencia "else" se ejecutará si la expresión "if " es false.

if 1 > 2:
  print("1 es mayor que 2")
else:
  print("1 no es mayor que 2")

1 no es mayor que 2, por lo que se ejecutará el código dentro de la instrucción "else".

También puedes usar una sentencia "elif" :

if 1 > 2:
  print("1 es mayor que 2")
elif 2 > 1:
  print("1 no es mayor que 2")
else:
  print("1 es igual a 2")

3. Bluce / Iterador

En Python, podemos iterar de diferentes formas. Hablaré de dos: while y for.

Bucle While: mientras la sentencia sea True, se ejecutará el código dentro del bloque. Por lo tanto, este código imprimirá el número del 1 al 10.

num = 1

while num <= 10:
    print(num)
    num += 1

El bucle while necesita una "condición de bucle". Si sigue siendo True, continúa iterando. En este ejemplo, cuando num es 11, la condición de bucle es igual a False.

Otro poco mas de código fundamental para entenderlo mejor:

condicion_de_bucle = True

while condicion_de_bucle:
    print("condicion de bucle sigue: %s" %(condicion_de_bluce))
    condicion_de_bluce = False

La condición de bucle es Verdadera, por lo que sigue iterando, hasta que la configuramos en Falso.

Para bucle: aplica la variable "num" al bloque, y la sentencia "for" la iterará por ti. Este código imprimirá el mismo código que while: del 1 al 10.

for i in range(1, 11):
  print(i)

¿Ves? Es tan simple. El rango comienza con 1 y va hasta el elemento 11.

Lista: Colección / arreglo / estructura de datos

Imagina que deseas almacenar el entero 1 en una variable. Pero tal vez ahora quieras almacenar 2. Y 3, 4, 5 …

¿Tengo otra forma de almacenar todos los enteros que quiero, pero no en millones de variables? Lo adivinaste, de hecho, hay otra forma de almacenarlos.

List es una colección que se puede usar para almacenar una lista de valores (como los enteros que desees). Así que usémoslo:

mis_enteros = [1, 2, 3, 4, 5]

Es muy simple. Creamos un arreglo y lo almacenamos en mis_enteros.

Pero tal vez te estés preguntando: "¿Cómo puedo obtener un valor de este arreglo?”

Gran pregunta. List tiene un concepto llamado index. El primer elemento obtiene el índice 0 (cero). El segundo obtiene 1, y así sucesivamente. Seguro que entiendes la idea.

Para hacerlo más claro, podemos representar el arreglo y cada elemento con su índice. Puedo dibujarlo:

Arreglo-index-1
Ilustración de Índice en un arreglo

Usando la sintaxis de Python, también es fácil de entender:

mis_enteros = [5, 7, 1, 3, 4]
print(mis_enteros[0]) # 5
print(mis_enteros[1]) # 7
print(mis_enteros[4]) # 4

Imagina que no quieres almacenar enteros. Solo quieres almacenar cadenas, como una lista de los nombres de tus familiares. El mío se vería algo así.:

nombres_de_familiares = [
  "Toshiaki",
  "Juliana",
  "Yuji",
  "Bruno",
  "Kaio"
]

print(nombres_de_familiares[4]) # Kaio

Funciona de la misma manera que los enteros. Agradable.

Acabamos de aprender cómo funcionan índices en Listas. Pero aún necesito mostrarte cómo podemos agregar un elemento a la estructura de datos de la Lista (un elemento a una lista).

El método más común para agregar un nuevo valor a una Lista es append. Veamos cómo funciona:

librero = []
librero.append("El Ingeniero Eficaz")
librero.append("La Semana Laboral de 4 Horas")
print(librero[0]) # El Ingeniero Eficaz
print(librero[1]) # La Semana Laboral de 4 Horas

append es súper simple. Solo necesitas aplicar el elemento (ej. "El Ingeniero eficaz") como parámetro de append.

Bueno, basta de listas. Hablemos de otra estructura de datos.

Diccionario: Estructura de datos clave-valor

Ahora sabemos que las listas están indexadas con números enteros. Pero, ¿qué pasa si no queremos usar números enteros como índices? Algunas estructuras de datos que podemos usar son índices numéricos, de cadena u otros tipos de índices.

Vamos a aprender sobre la estructura de datos del Diccionario. El diccionario es una colección de pares clave-valor. Así es como se ve:

ejemplo_de_diccionario = {
  "clave1": "valor1",
  "clave2": "valor2",
  "clave3": "valor3"
}

La clave es el índice que apunta al valor. ¿Cómo accedemos al valor del Diccionario? Lo adivinaste, usando la llave. Vamos a intentarlo:

diccionario_tk = {
  "nombre": "Leandro",
  "sobrenombre": "Tk",
  "nacionalidad": "Brasilenio"
}

print("Mi nombre es %s" %(diccionario_tk["nombre"])) # Mi nombre es Leandro
print("Pero tu me puedes llamar %s" %(diccionario_tk["sobrenombre"])) # But you can call me Tk
print("Y por cierto soy %s" %(diccionario_tk["nationalidad"])) # Y por cierto soy Brasilenio

Creé un diccionario sobre mí. Mi nombre, sobrenombre y nacionalidad. Esos atributos son las claves del diccionario.

A medida que aprendimos a acceder la Lista usando índice, también usamos índices (claves en el contexto del diccionario) para acceder al valor almacenado en el Diccionario.

En el ejemplo, imprimí una frase sobre mí usando todos los valores almacenados en el diccionario. Bastante simple, ¿verdad?

Otra cosa interesante del diccionario es que podemos usar cualquier cosa como valor. En el diccionario que creé, quiero agregar la clave "edad" y mi edad entera real en él:

diccionario_tk = {
  "nombre": "Leandro",
  "sobrenombre": "Tk",
  "nacionalidad": "Brasilenio",
  "edad": 24
}

print("Mi nombre es %s" %(diccionario_tk["nombre"])) # Mi nombre es Leandro
print("Pero me puedes llamar %s" %(diccionario_tk["sobrenombre"])) # Pero me puedes llamar Tk
print("Y por cierto soy %i y %s" %(dictionary_tk["edad"], diccionario_tk["nacionalidad"])) # Y por cierto soy Brasilenio

Aquí tenemos un par de clave (edad) de valor (24) que usa cadena como clave y entero como valor.

Como hicimos con las Listas, aprendamos a agregar elementos a un Diccionario. La clave que apunta a un valor es una gran parte de lo que es el Diccionario. Esto también es cierto cuando hablamos de agregarle elementos:

diccionario_tk = {
  "nombre": "Leandro",
  "sobrenombre": "Tk",
  "nacionalidad": "Brasilenio"
}

diccionario_tk['edad'] = 24

print(diccionario_tk) # {'nacionalidad': 'Brasilenio', 'edad': 24, 'sobrenombre': 'Tk', 'nombre': 'Leandro'}

Solo necesitamos asignar un valor a una clave de Diccionario. Nada complicado aquí, ¿verdad?

Iteración: Bucle a través de estructuras de datos

Como aprendimos en los conceptos básicos de Python, la iteración de la Lista es muy simple. Los desarrolladores de Python usamos comúnmente bucles For. Hagámoslo:

librero = [
  "El Ingeniero Eficaz",
  "La semana laboral de 4 horas",
  "Cero a Uno",
  "Inicio Lean",
  "Enganchar"
]

for libro in librero:
    print(libro)

Por lo tanto, para cada libro en el librero, lo imprimimos (podemos hacer todo con él). Bastante simple e intuitivo. Ese es Python.

Para una estructura de datos hash, también podemos usar el bucle for, pero aplicamos la clave :

diccionario = { "alguna_clave": "algun_valor" }

for clave in diccionario:
    print("%s --> %s" %(clave, diccionario[clave]))
    
# alguna_clave --> algun_valor

Este es un ejemplo de cómo usarlo. Para cada clave en el diccionario , imprimimos la clave y su valor correspondiente.

Otra forma de hacerlo es usar el método iteritems.

diccionario = { "alguna_clave": "algun_valor" }

for clave, valor in diccionario.items():
    print("%s --> %s" %(clave, valor))

# alguna_clave --> algun_valor

Nombramos los dos parámetros como clave y valor, pero no es necesario. Podemos nombrar nada. Vamos a ver:

diccionario_tk = {
  "nombre": "Leandro",
  "sobrenombre": "Tk",
  "nacionalidad": "Brasilenio",
  "edad": 24
}

for attributo, valor in diccionario_tk.items():
    print("Mi %s es %s" %(attributo, valor))
    
# Mi nombre is Leandro
# My sobrenombre es Tk
# My nacionalidad es Brasilenio
# Mi edad es 24

Podemos ver que usamos atributo como parámetro para la clave del diccionario, y funciona correctamente. ¡Órale!

Clases y objetos

Un poco de teoría:

Los objetos son una representación de objetos del mundo real como coches, perros o bicicletas. Los objetos comparten dos características principales: datos y comportamiento.

Los automóviles tienen datos, como el número de ruedas, el número de puertas y la capacidad de asientos, también muestran un comportamiento: pueden acelerar, detenerse, mostrar cuánto combustible queda y muchas otras cosas.

Identificamos los datos como atributos y el comportamiento como métodos en la programación orientada a objetos. De nuevo:

Datos → atributos and comportamiento → métodos

Y una Clase es el plano a partir del cual se crean objetos individuales. En el mundo real, a menudo encontramos muchos objetos con el mismo tipo. Como los coches. Todos de la misma marca y modelo (y todos tienen motor, ruedas, puertas, etc.). Cada automóvil fue construido a partir del mismo conjunto de planos y tiene los mismos componentes.

Modo de programación orientado a objetos de Python: ACTIVADO

Python, como lenguaje de programación orientado a objetos, tiene estos conceptos: clase y objeto.

Una clase es un plano, un modelo para sus objetos.

De nuevo, una clase es solo un modelo, o una forma de definir atributos y comportamiento (como hablamos en la sección teoría). Por ejemplo, una clase de vehículo tiene sus propios atributos que definen qué objetos son vehículos. El número de ruedas, el tipo de tanque, la capacidad de asientos y la velocidad máxima son atributos de un vehículo.

Con esto en mente, veamos la sintaxis de Python para las clases:

class Vehiculo:
    pass

Definimos clases con una sentencia de clase — y eso es todo. Fácil, ¿no?

Los objetos son instancias de una clase. Creamos una instancia nombrando la clase.

carro = Vehiculo()
print(carro) # <__main__.Vehiculo instancia en 0x7fb1de6c2638>

Aquí carro es un objeto (o instancia) del Vehiculo de clase.

Recuerda que nuestra clase de vehículo tiene cuatro atributos: número de ruedas, tipo de tanque, capacidad de asientos y velocidad máxima. Establecemos todos estos atributos al crear un objeto vehículo. Así que aquí, definimos nuestra clase para recibir datos cuando la inicia:

class Vehiculo:
    def __init__(self, numero_de_ruedas, tipo_de_tanque, capacidad_de_asientos, velocidad_maxima):
        self.numero_de_ruedas = numero_de_ruedas
        self.tipo_de_tanque = tipo_de_tanque
        self.capacidad_de_asientos = capacidad_de_asientos
        self.velocidad_maxima = velocidad_maxima

Usamos el método init. Lo llamamos un método constructor. Así que cuando creamos el objeto vehículo, podemos definir estos atributos. Imaginen que nos encanta el Tesla Modelo S, y queremos crear este tipo de objeto. Tiene cuatro ruedas, funciona con energía eléctrica, tiene espacio para cinco asientos y la velocidad máxima es de 250 km/hora (155 mph). Vamos a crear este objeto:

tesla_modelo_s = Vehiculo(4, 'electrico', 5, 250)

Cuatro ruedas + "tipo tanque" eléctrico + cinco asientos + velocidad máxima de 250 km / hora.

Todos los atributos están configurados. Pero, ¿cómo podemos acceder a los valores de estos atributos? Enviamos un mensaje al objeto preguntando por ellos. Lo llamamos método. Es el comportamiento del objeto. Vamos a implementarlo:

class Vehiculo:
    def __init__(self, numero_de_ruedas, tipo_de_tanque, capacidad_de_asientos, velocidad_maxima):
        self.numero_de_ruedas = numero_de_ruedas
        self.tipo_de_tanque = tipo_de_tanque
        self.capacidad_de_asientos = capacidad_de_asientos
        self.velocidad_maxima = velocidad_maxima

    def numero_de_ruedas(self):
        return self.numero_de_ruedas

    def numero_de_ruedas_establecido(self, numero):
        self.numero_de_ruedas = numero

Esta es una implementación de dos métodos: numero_de_ruedas y numero_de_ruedas_estabecido. Lo llamamos getter y setter. Porque el primero obtiene el valor del atributo, y el segundo establece un nuevo valor para el atributo.

En Python, podemos hacer eso usando @property (decoradores) para definir getters y setters. Vamos a verlo con código:

class Vehiculo:
    def __init__(self, numero_de_ruedas, tipo_de-tanque, capacidad_de_asientos, velocidad_maxima):
        self.numero_de_ruedas = numero_de_ruedas
        self.tipo_de-tanque = tipo_de-tanque
        self.capacidad_de_asientos = capacidad_de_asientos
        self.velocidad_maxima = velocidad_maxima
    
    @property
    def numero_de_ruedas(self):
        return self.__numero_de_ruedas
    
    @numero_de_ruedas.setter
    def numero_de_ruedas(self, numero):
        self.__numero_de_ruedas = numero

Y podemos usar estos métodos como atributos:

tesla_modelo_s = Vehiculo(4, 'electrico', 5, 250)
print(tesla_modelo_s.nuemro_de_ruedas) # 4
tesla_modelo_s.numero_de_ruedas = 2 # ajuste del número de ruedas a 2
print(tesla_modelo_s.numero_de_ruedas) # 2

Esto es ligeramente diferente de los métodos de definición. Los métodos funcionan como atributos. Por ejemplo, cuando establecemos el nuevo número de ruedas, no aplicamos dos como parámetro, sino que establecemos el valor 2 en numero_de_ruedas. Esta es una forma de escribir código de getter y setter pitónicos.

Pero también podemos usar métodos para otras cosas, como el método "hacer_ruido". Vamos a ver:

class Vehiculo:
    def __init__(self, numero_de_ruedas, tipo_de_tanque, capacidad_de_asientos, velocidad_maxima):
        self.numero_de_ruedas = numero_de_ruedas
        self.tipo_de_tanque = tipo_de_tanque
        self.capacidad_de_asientos = capacidad_de_asientos
        self.velocidad_maxima = velocidad_maxima

    def hacer_ruido(self):
        print('VRUUUUUUUM')

Cuando llamamos a este método, simplemente devuelve una cadena " VRRRRUUUUM.”

tesla_modelo_s = Vehiculo(4, 'electrico', 5, 250)
tesla_modelo_s.hacer_ruido() # VRUUUUUUUM

Encapsulación: Ocultar información

La encapsulación es un mecanismo que restringe el acceso directo a los datos y métodos de los objetos. Pero al mismo tiempo, facilita el funcionamiento de esos datos (métodos de objetos).

"La encapsulación se puede usar para ocultar miembros de datos y funciones de miembros. Bajo esta definición, encapsulación significa que la representación interna de un objeto generalmente se oculta fuera de la definición del objeto."— Wikipedia

Toda la representación interna de un objeto está oculta desde el exterior. Solo el objeto puede interactuar con sus datos internos.

Primero, necesitamos entender cómo funcionan las variables y métodos de instancia públicos y no públicos.

Variables de instancia pública

Para una clase Python, podemos inicializar una variable de instancia pública dentro de nuestro método constructor. Veamos esto.

Dentro del método constructor:

class Persona:
    def __init__(self, nombre):
        self.nombre = nombre

Aquí aplicamos el valor nombre como argumento a la variable de instancia pública.

tk = Persona('TK')
print(tk.nombre) # => TK

Dentro de la clase:

class Persona:
    nombre = 'TK'

Aquí, no necesitamos aplicar el nombre como argumento, y todos los objetos de instancia tendrán un atributo de clase inicializado con TK.

tk = Persona()
print(tk.nombre) # => TK

Ahora hemos aprendido que podemos usar variables de instancia pública y atributos de clase. Otra cosa interesante de la parte pública es que podemos administrar el valor de la variable. ¿Qué quiero decir con eso? Nuestro objeto puede administrar su valor de variable: Obtener y Establecer valores de variable.

Teniendo en cuenta la clase Persona, queremos establecer otro valor en su variable nombre:

tk = Persona('TK')
tk.nombre = 'Kaio'
print(tk.nombre) # => Kaio

Allá vamos. Acabamos de establecer otro valor (`kaio`) a la variable de instancia nombre y actualizó el valor. Así de simple. Como es una variable pública, podemos hacerlo.

Variable de instancia no pública

No usamos el término "privado" aquí, ya que ningún atributo es realmente privado en Python (sin una cantidad de trabajo generalmente innecesaria). - PEP 8

Como variable de instancia pública, podemos definir la variable de instancia no pública tanto dentro del método constructor como dentro de la clase. La diferencia de sintaxis es: para variables de instancia no públicas , use un guion bajo ( _ ) antes del nombre de la variable.

"Las variables de instancia 'Privadas' a las que no se puede acceder excepto desde el interior de un objeto no existen en Python. Sin embargo, hay una convención que es seguida por la mayoría del código Python: un nombre con un prefijo de subrayado (por ejemplo, _spam) debe tratarse como una parte no pública de la API (ya sea una función, un método o un miembro de datos) " - Python Software Foundation

Este es un ejemplo:

class Persona:
    def __init__(self, nombre, correo_electronico):
        self.nombre = nombre
        self._correo_electronico = correo_electronico

¿Viste la variable de correo electrónico? Así es como definimos una variable no pública :

tk = Persona('TK', 'tk@mail.com')
print(tk._correo_electronico) # tk@mail.com
Podemos acceder y actualizarlo. Las variables no públicas son solo una convención y deben tratarse como una parte no pública de la API.

Así que usamos un método que nos permite hacerlo dentro de nuestra definición de clase. Implementemos dos métodos (correo electrónico y actualizar_correo_electronico) para entenderlo:

class Persona:
    def __init__(self, nombre, correo_electronico):
        self.nombre = nombre
        self._correo_electronico = correo_electronico

    def actualizar_correo_electronico(self, nuevo_correo_electronico):
        self._email = nuevo_correo_electronico

    def correo_electronico(self):
        return self._correo_electronico

Ahora podemos actualizar y acceder a variables no públicas utilizando esos métodos. Veamos:

tk = Persona('TK', 'tk@mail.com')
print(tk.correo_electronico()) # => tk@mail.com
# tk._correco_electronico = 'nuevo_tk@mail.com' -- tratar como una parte no pública de la API de clase
print(tk.correo_electronico()) # => tk@mail.com
tk.actualizar_correo_electronico('nuevo_tk@mail.com')
print(tk.correo_electronico()) # => nuevo_tk@mail.com
  1. Iniciamos un nuevo objeto con nombre TK y correo electrónico tk@mail.com
  2. Imprimió el correo electrónico accediendo a la variable no pública con un método
  3. Intenté establecer un nuevo correo electrónico fuera de nuestra clase
  4. Necesitamos tratar la variable no pública como parte no pública de la API
  5. Se actualizó la variable no pública con nuestro método de instancia
  6. ¡Éxito! Podemos actualizarlo dentro de nuestra clase con el método helper

Método Público

Con los métodos públicos, también podemos usarlos fuera de nuestra clase:

class Persona:
    def __init__(self, nombre, edad):
        self.nombre = nombre
        self._edad = edad

    def muestra_edad(self):
        return self._edad

Vamos a probarlo:

tk = Persona('TK', 25)
print(tk.muestra_edad()) # => 25

Genial, podemos usarlo sin ningún problema.

Método no público

Pero con métodos no públicos no podemos hacerlo. Implementemos la misma clase Persona, pero ahora con un método no público muestra_edad usando un guion bajo (_).

class Persona:
    def __init__(self, nombre, edad):
        self.nombre = nombre
        self._edad = edad

    def _muestra_edad(self):
        return self._edad

Y ahora, intentaremos llamar a este método no público con nuestro objeto:

tk = Person('TK', 25)
print(tk._muestra_edad()) # => 25
Podemos acceder y actualizarlo. Los métodos no públicos son solo una convención y deben tratarse como una parte no pública de la API.

Aquí hay un ejemplo de cómo podemos usarlo:

class Persona:
    def __init__(self, nombre, edad):
        self.nombre = nombre
        self._edad = edad

    def muestra_edad(self):
        return self._obten_edad()

    def _obten_edad(self):
        return self._edad

tk = Persona('TK', 25)
print(tk.muestra_edad()) # => 25

Aquí tenemos un método no público _obten_edad y un método público muestra_edad. El muestra_edad puede ser utilizado por nuestro objeto (fuera de nuestra clase) y el _obten_edad solo se usa dentro de la definición de su clase (dentro del método muestra_edad). Pero de nuevo: como una cuestión de convención.

Resumen de Encapsulación

Con la encapsulación podemos asegurarnos de que la representación interna del objeto esté oculta desde el exterior.

Herencia: comportamientos y características

Ciertos objetos tienen algunas cosas en común: su comportamiento y características.

Por ejemplo, heredé algunas características y comportamientos de mi padre. Heredé sus ojos y cabello como características, y su impaciencia e introversión como comportamientos.

En la programación orientada a objetos, las clases pueden heredar características comunes (datos) y comportamiento (métodos) de otra clase.

Veamos otro ejemplo e impleméntelo en Python.

Imagina un coche. El número de ruedas, la capacidad de asientos y la velocidad máxima son atributos de un automóvil. Podemos decir que una clase de coche eléctrico hereda estos mismos atributos de la clase de coche normal.

class Carro:
    def __init__(self, numero_de_ruedas, capacidad_de_asientos, velocidad_maxima):
        self.numero_de_ruedas = numero_de_ruedas
        self.capacidad_de_asientos = capacidad_de_asientos
        self.velocidad_maxima = velocidad_maxima

Nuestra clase de Carro implementada:

mi_carro = Carro(4, 5, 250)
print(mi_carro.numero_de_ruedas)
print(mi_carro.capacidad_de_asientos)
print(mi_carro.velocidad_maxima)

Una vez iniciado, podemos usar todas las variables de instancia creadas. Agradable.

En Python, aplicamos una clase padre a la clase hija como parámetro. Una clase de carroElectrico puede heredar de nuestra clase de Car.

class CarroElectrico(Carro):
    def __init__(self, numero_de_ruedas, capacidad_de_asientos, capacidad_maxima):
        Carro.__init__(self, numero_de_asientos, capacidad_de_asientos, capacidad_maxima)

Así de simple. No necesitamos implementar ningún otro método, porque esta clase ya lo tiene (heredado de la clase Carro). Vamos a probarlo:

mi_carro_electrico = CarroElectrico(4, 5, 250)
print(mi_carro_electrico.numeros_de_asientos) # => 4
print(mi_carro_electrico.capacidad_de_asientos) # => 5
print(mi_carro_electrico.capacidad_maxima) # => 250

¡Eso es todo!

Aprendimos muchas cosas sobre los conceptos básicos de Python:

  • Cómo funcionan las variables de Python
  • Cómo funcionan las sentencias condicionales de Python
  • Cómo funciona el bucle de Python (while y for)
  • Cómo usar Listas: Colección / Arreglo
  • Colección de Clave-Valor del Diccionario
  • Cómo podemos iterar a través de estas estructuras de datos
  • Objetos y Clases
  • Atributos como datos de objetos
  • Métodos como comportamiento de los objetos
  • Uso de getters y setters de Python y decorador de propiedades
  • Encapsulación: ocultar información
  • Herencia: comportamientos y características

Felicidades! Completaste esta densa pieza de contenido sobre Python.

Para más historias y publicaciones sobre mi viaje aprendiendo y dominando la programación, sigue mi publicación The Renaissance Developer.

Diviértete, sigue aprendiendo y siempre sigue programando.

Mi Twitter y Github. 😀