Crea una cuenta o inicia sesión

¡Continúa aprendiendo sin ningún costo! Únete y comienza a potenciar tu carrera

Curso Profesional de Python

Curso Profesional de Python

Facundo García Martoni

Facundo García Martoni

Tipado estático en Python

5/21
Recursos

Aportes 70

Preguntas 16

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Yo aquí veo un área de oportunidad para tener mejores prácticas de código.
Este es el tipo de cosas que esperaba aprender en un curso avanzado.
Demasiada información nueva para mi en esta clase, tengo muchas preguntas sobre esto y me gusta. Espero que se resuelvan en las siguientes clases.

Tipado estático en Python

.
Para hacer que Python sea de tipado estático es necesario agregar algo de sintaxis adicional a lo aprendido, además, esta característica solo se puede aplicar a partir de la versión 3.6.

# De esta manera se declara una variable, se colocan los dos puntos (:), el tipo de dato y para finalizar se usa el signo igual para asignar el valor a la variable.

<variable> : <tipo_de_dato> = <valor_asignado>

a: int = 5
print(a)

b: str = "Hola"
print(b)

c: bool = True
print(c)

Del mismo modo se puede usar esta metodología de tipado en Python a funciones adicionando el signo menos a continuación del signo mayor que para determinar el tipo de dato. Ejemplo:

def <nombre_func> ( <parametro1> : <tipo_de_dato>, <parametro2> : <tipo_de_dato> ) ->  <tipo_de_dato> :
	pass

def suma(a: int, b: int) -> int :
	return a + b

print(suma(1,2))

# 3

Existe una librería de fabrica que viene preinstalada con Python que se llama typing, que es de gran utilidad para trabajar con tipado con estructuras de datos entre la versión 3.6 y 3.9, entonces:
.

from typing import Dict, List

positives: List [int] = [1,2,3,4,5]

users: Dict [str, int] = {
	"argentina": 1.
	"mexico": 34,
	"colombia": 45,
}

countries: List[Dict[str, str]] = [
	{
		"name" : "Argentina",
		"people" : "45000",
	},
	{
		"name" : "México",
		"people" : "9000000",
	},
	{
		"name" : "Colombia",
		"people" : "99999999999",
	}
]
from typing import Tuple, Dict, List

CoordinatesType = List[Dict[str, Tuple[int, int]]]

coordinates: CoordinatesType = [
	{
		"coord1": (1,2),
		"coord2": (3,5)
	},
	{
		"coord1": (0,1),
		"coord2": (2,5)
	}
]

Modulo mypy

.
El modulo mypy se complementa con el modulo typing ya que permitirá mostrar los errores de tipado debil en Python.

Los lenguajes de tipado fuerte y estático orgullosos porque estamos aplicando este tipo de conceptos en Python. 😎👌
.

Recomiendo usar Optional[], de la libreria typing, es para cuando ocupamos retornar None u otra variable

def foo() -> Optional[List]:
  if b:
    return []
  else:
    None

Existe Pydantic que es un validador de tipos. pydantic

JavaScript también necesitaba un tipado más estático, entonces crearon TypeScript. Un tipado más fuerte no solo da mucho feedback al programador, sino que se pueden evitar muchos errores y el programa puede ser más robusto.

Resumen express
Para decirle a python de qué tipo de dato será una variable utilizaremos la siguiente sintaxis:
Ejemplos

  • En el caso de los int :
    total: int = 120
  • En el caso de los strings :
    frase: str = ‘Hola mundo’
  • En el caso de los booleanos :
    hambre: bool = True
  • En el caso de los float :
    velocidad: float = 48.2

Si se fijan es siempre la misma sintaxis, primero el nombre de la variable, después su tipo y su valor.

Para las estructuras de datos
Con las listas, diccionarios y tuplas necesitaremos importar la librería typing y sus respectivos módulos, los cuales algunos son Dict, List y Tuple.
Ejemplos

  • Para una lista :
    edades: List[int] = [24, 18, 22]

  • Para un **diccionario ** (primero el tipo de la llave y luego el del valor):
    poblacion: Dict[str, int] = { ‘México’: 131214372, ‘Colombia’: 50.374.000 }

  • Para una **tupla ** declararémos el tipo de cada valor individualmente, no de manera general:
    constantes: Tuple[int, str, int, int, str] = ( 2, ‘Hola’, 4, 6, ‘Adiós’ )

Ahora que sabes las bases
Puedes replicar todo esto en cualquier otra cosa, por ejemplo al declarar los argumentos de una función, es exactamente la misma sintaxis, o al hacer una lista con diccionarios dentro, es exactamente lo mismo a anidar lo anterior.

Estos son los ejemplos de la clase (con algo extra)

"""
Pratice Static Typing
"""

from typing import Dict, List, Tuple

# Example 1
a: int = 1
b: str = 'I am a string'
c: bool = True

# Example 2
def add(a: int, b: int) -> int:
    return a + b

# Example 3
positives_numbers: List[int] = [1, 2, 3, 4, 6, 6, 7, 8]

# Example 4
users_at_platzi: Dict[str, int] = {
    'Venezuela': 5000,
    'Mx': 100000,
    'Argentina': 2000
}

# Example 5
countries: List[Dict[str, str]] = [
    {
        'name': 'Venezuela',
        'capital': 'Caracas'
    },
    {
        'name': 'Argentina',
        'capital': 'Buenos Aires'
    }
]

# Example 6
num: Tuple[int, bool, str, float] = (1, False, 'Hola', 3.5)

# Example 7
msg: str = 'This are the coordinates'
CoordinatesType = list[Dict[str, Tuple[int, int, str]]]

coordinates: CoordinatesType = [
    {
        'place1': (4, 5, msg),
        'place2': (10, 45, msg),
    },
        {
        'place1': (42, 555, msg),
        'place2': (104, 945, msg),
    },
]

Tipado estático en Python

  • Podemos convertir a Python a un lenguaje de tipado estático 🤯. Para eso, usamos Static Typing, y es muy sencillo, solo debemos añadir una sintaxis adicional, en la cual declaramos variables con su tipo.

    a: int = 5
    b: str = 'Hola'
    c: bool = True
    
    print(a, b, c)
    

    Esto funciona desde Python 3.6 👀. Para hacerlo con funciones (con sus variables y con lo que retorna la función):

    def suma(a: int, b: int) -> int:
    	return a + b
    
    print(suma(1, 2))
    

    Si le pasamos strings a la función suma, si funcionará y nos va a regresar las strings sumadas, para evitar esto, debemos añadir un módulo.

  • Podemos hacer tipado en estructuras de datos. Para definir que una variable es de un tipo (de una estructura de datos), desde la versión 3.9, podemos hacerlo con las palabras claves de ese tipo. Antes de la versión 3.9, es con:

    from typing import Dict, List
    
    positives: List[int] = [1, 2, 3, 4, 5]
    
    users: Dict[str, int] = {
    	'argentina': 1,
    	'mexico': 34,
    	'colombia': 45
    }
    
    countries: List[Dict[str, str]] = [
    	{
    		'name':'Argentina'
    		'people':'45000'
    	},
    	{
    		'name':'México'
    		'people':'900000'
    	},
    	{
    		'name':'Colombia'
    		'people':'9999999'
    	}
    ]
    
  • Podemos hacer lo mismo con las tuplas:

    from typing import Tuple
    
    numbers: Tuple[int, float, int] = (1, 0.5, 1)
    
  • Podemos definir nuestros propios tipos de variable y usarlas:

    from typing import Tuple, Dict, List
    
    CoordinateType = List[Dict[str, Tuple[int, int]]]
    
    coordinates: CoordinateType = [
    	{
    		'coord1': (1, 2),
    		'coord2': (3, 5)
    	},
    	{
    		'coord1': (0, 1),
    		'coord2': (2, 5)
    	}
    ]
    
  • Para que Python considere este tipado estático y no se salte, es con el módulo mypy que nos detiene cuando hay errores de tipado 👀.

Resumen de la clase

Tipado estático en Python

FALLBACK_PHONE = '+e00000000'

def get_phone():
	phone = input('Give me your phone: ')
	if not phone:
		return FALLBACK_PHONE.round()
	return int(phone)

def run():
	my_phone = get_phone()
	print(f'Your phone is: {my_phone}')

run()
print("Hello, world!")
# some code
a = 1
print(type(a))

# Hello, world!
# <class 'int'>

Se puede hacer de la siguiente forma: feacture desde la versión: python 3.6

a: int = 5
print(a)  

b: str = 'hola'
print(b)

c: bool = True
print(c)

# 5
# hola
# True

Puedo definir el tipo de variable a recibir y retornar def suma(a: int, b: int) -> int:

(aun se esta probando)

def suma(a: int, b: int) -> int:
	return a + b

print(suma(1, 2)

# 3
def suma(a: int, b: int) -> int:
	return a + b

print(suma("1", "2")

# 12
# se define el tipo de dato de las tuplas
from typing import Dict, Tuple, List

numbers: Tuple[int, float, int] = (1, 0.5, 1)
CoordinatesTypes = list[Dict[str, Tuple[int, int]]]
coordinates: CoordinatesTypes = [
    {
        'coord1': (1, 2),
        'coord2': (3, 4)
    },
    {
        'coord1': (0, 2),
        'coord2': (3, 5)
    },
]

Ventajas: nos va a devolver los errores antes de que el programa se ejecute

mypy nos permite trabajar con tipos y mostrar errores en consola, complementando con el modulo typing

‘casteo’ … proviene de CASTING, que hace relación a la transformación del tipo de variable,
ejemplo:

x = int("3")     # x será 3
y = str(2)       # y  será '2'
z = str(3.0)    # z será '3.0' 

Mypy es un verificador de tipo estático opcional para Python que tiene como objetivo combinar los beneficios de la escritura dinámica (o “pato”) y la escritura estática.

Estuve practicando el uso del tipado estático con algunos retos y la verdad que agradezco mucho haber tomado esta clase porque me hizo la vida más fácil al momento de crear mis algoritmos. Principalmente al pasar por parámetros es muy útil identificar tipo de dato para saber que metodos podía utilizar y cuales no.

Tipado estático en Python
Documentación oficial del tipado estático en Python
El tipado estático nos hará evitar errores de tipado antes de que el programa se ejecute.

Tipado estático en Python

Documentación oficial del tipado estático en Python

El tipado estático nos hará evitar errores de tipado antes de que el programa se ejecute.

a: int = 5
print(a) # 5

b: str = 'Hola'
print(b) # Hola

c: bool = True
print(c) # True

Esta sintaxís está disponible desde la versión 3.6 de Python.

def suma(a: int, b: int) -> int:
  return a + b

print(suma(1,2)) # 3
def suma(a: int, b: int) -> int:
  return a + b

print(suma('1','2')) # 12 😅

Usando tipado en estructuras de datos. Desde la versión 3.6 debemos importar librerias.

from typing import Dict, List

positives: List[int] = [1,2,3,4,5]

users: Dict[str, int] = {
  'argentina': 1,
  'mexico': 34,
  'colombia': 45,
}

countries: List[Dict[str,str]] = [
  {
    'name': 'Argentina',
    'people': '450000', # Cuatrocientos cincuenta mil
  },
  {
    'name': 'México',
    'people': '90000000', # Noventa millones
  },
  {
    'name': 'Colombia',
    'people': '99999999999', #novecientos noventa y nueve mil millones novecientos mil novecientos noventa y nueve
  }
]
from typing import Tuple

numbers: Tuple[int, float, int] = (1, 0.5, 1)
from typing import Tuple, Dict, List

CoordinatesType = List[Dict[str, Tuple[int, int]]]

#Una variable que es de tipo CoordinatesType 🤯
coordinates: CoordinatesType = [
  {
    'coord1': (1,2),
    'coord2': (3,5),
  },
  {
    'coord1': (0,1),
    'coord2': (2,5),
  },
]

Ventajas de esto: claridad del código.

Creación de un tipo con clases

En la clase no se evaluó, el caso en que un diccionario debe tener una llave concreta y esa llave es de un tipo particular. Les dejo esta captura que muestra como crear este escenario y como verificarlo.

TIPADO ESTÁTICO EN PYTHON

  • mypy -> módulo que permite trabajar con tipos en Python y permite ver los errores en consola.
    Se complementa con el módulo Typing.
    VENTAJAS

  • Aporta claridad y calidad al código. Así va a ser más entendible para otros desarrolladores.

  • Nos devuelve los errores antes de que el programa se ejecute.

  • None o cualquier tipo
from typing import Optional

def get_number() -> Optional[int]:
    """
	Esta function retorna int or None
	"""
	....
  • Más de un tipo
from typing import Union

def get_number() -> Union[int, float]:
	"""
	Esta function retorna int or float
	"""
	....

Las ventajas de utilizar tipado estático en python:

  1. Nos aporta claridad del código.
  2. Nos da calidad a lo que estamos programando.
  3. Nuestro código va a ser mas entendible a otros programadores si trabajamos con tipos.
  4. Nos va a devolver los errores antes del que programa se ejecute. ¿Cómo? Bueno la siguiente clase seguro lo vamos a ver 😄. Éxitos codeando!!

Wow increíble esta funcionalidad de Python 😃

Typing is a new feature! > 3.6

Module mypy for work with typing and show errors before execution.
Python is a Dynamic and Strong Typing language.
Module typing defines complex typing.
Apply Static Typing in Python to increase our quality and clarity. Also, the deep Errors of our code are shown before that execution.

Facundo es un gran instructor, explica muy bien

Python es de tipado dinámico. Esto puede ser peligroso porque puede ser que haya un error no detectado que salga a la luz cuando estamos ejecutando el código.

  • Se puede convertir a python de tipado dinámico a tipado estático…

ASÍ SE VE UN CÓDIGO COMÚN EN PYTHON:

FALLBACK_PHONE = '0+e000000000'

def get_phone():
    phone = input(' Give me your phone: ')
    if not phone:
        return FALLBACK_PHONE.round()
    return int(phone)

def run():
    my_phone = get_phone()
    print (f'Your phone is : {my_phone}')
    
run()

Pero esto puede generar un error a la hora de que alguien no escriba un número y le de enter. Python de cierta manera puede confundirse con el tipo de dato.

Static Typing

Para hacer de python un lenguaje estático, se le añade una sintaxis adicional


a: int = 5
print(a)
b: str = "hola"
print(b)
c: bool = True
print(c)

Lo anterior visto es la declaración de variables. Se le coloca el nombre de la variable, dos puntos espacio y el tipo de dato.


def suma(a: int, b: int) -> int:
    return a + b

print(suma(1,2))
# 3
print(suma('1','2'))

# 12

Con esta flecha obligamos a python a que regrese un entero(int).

Existn versiones de python donde hay que importar una serie de funciones para poder volverlo estático:


from typing import Dict,List
positives: List[int] = [1,2,3,4,5]

users: Dict[str, int] = {
'argentina':1,
'mexico': 2,
'colombia':3,

}
countries: List[Dict[str,str]] = [
{
    'name': 'argentina',
    'people': '123131'
},
{
    'name': 'mexico',
    'people': '131123'
},
{
    'name': 'colombia',
    'people': '431234'
},
]

Aclaramos con la función Dict y List que clase de tipo vamos usarla.

from typing import Tuple

numbers:Tuple[int, float, int] = (1,0.4,4)

Con las tuplas, como son inmutable, se puede definir de que tipo son cada uno de los elementos que contiene.

from typing import Tuple,Dict,List
CoordinatesType = List[Dict[str, Tuple[int, int]]]

coordinates: CoordinatesType = [
    {
        'coord1': (1,2),
        'coord2': (3,4),
    },
    {
        'coord1': (5,6),
        'coord2': (7,8),
        
    },
    

en python puedes crear una variable que contenga el tipo que usarás para asignar otras variables

módulo mypy

Este módulo nos permite a nosotros trabajar con tipos en python y se complementa con el módulo typing que viene con python que nos permite definir tipos complejos

Ventajas

  1. Nos aporta claridad y calidad al código, para hacerlo mucho más entendible para los programadores si trabajamos con tipos
  2. ejecuta los errores antes de que lo haga el programa. Muestra errores que podríamos tener en capas profundas de nuestro código
def is_primo(numero: int) -> bool:
    if numero == 1:
        return False
    if numero == 2:
        return True

    for i in range(2, numero-1):
        if numero % i == 0:
            return False
    return True


def main():
    print(is_primo(97))


if __name__ == '__main__':
    main()
 

Vean el código público de AlphaFold de la empresa DeepMind:

https://github.com/deepmind/alphafold/blob/main/alphafold/model/model.py

Poder hacer uso de la definición de tipos como se declara CoordinateType me parece algo poderosísimo. Así se podría tener un módulo con todos los tipos especiales de datos de los que hace uso nuestro programa manteniento la legibilidad y sobre todo agregando el super poder de tipado estático.

En python 3.9 la definición del tipo CoordinatesType puede hacerse de la siguiente forma:

CoordinatesType = list[dict[str, tuple[int, int]]]

Static type in python

Is possible change python to type static with static typing.

variable: type = value

examples:

  • variable_1: int = 10
  • variable_2: str = “Platzi”
  • For python 3.9
def sum(variable_1: str, variable_2: str) -> int:
	return a + b

  print(sum(1,2))

  12
  • Version 3.6 >= and < 3.9
from typing import Dict, List, Tuple

List[int] = [1,2,3]
Dict[str, int] = {
	"one": 1,
	"two": 2,
	"three": 3,
}

numbers: Tuple[int, float, int] = (1, 1.55, 10)

While you are programming the module mypy show you the errors in code before it’s processed. Similar to a static language.

Tipado estático en Python

Para evitar errores y no nos rompa el programa en el momento de la ejecución.

print('Hello, world!')
# some code

a = 1
print(type(a))

RESPUESTAS:
# Hello, world!
# <class 'int'>

Static Typing

Pasamos a trabajar como si fuera Java.

a: int = 5
print(a)

>> 5

b: str = 'Hi!'
print(b)

>> Hi!

c: bool = True
print(c) 

>> True

def suma(a: int, b:int) -> int:
	return a + b

print(suma(1, 3))

>> 3

def suma(a: int, b:int) -> int:
	return a + b

print(suma('1', '3'))

>> 13

Este ejemplo muestra un tipado pero en vez de usar datos primitivos se usará estructuras de datos, listas y diccionario.

from typing import Dict, List

positive: List[int] = [1, 2, 3, 4, 5]

users: Dict[str,int] = {
		'italia': 2,
		'suiza': 23,
		'alemania': 34,
}

countries: List[Dict[str, str]] = [
		{
				'name': 'Rusia',
				'people': 483764928,
		},
		{
				'name': 'United State',
				'people': 21321376243928,
		},
		{
				'name': 'Belgica',
				'people': 903742221328,
		},
]
from typing import Tuple

numbers: Tuple[int, float, int] = (1, 0.5, 1)
from typing import Tuple, Dist, List

CoordibatesType = List[Dict[str, Tuple[int, int]]]

coordinates: CoordinatesType = [
		{
				'coord1': (1, 2),
				'coord2': (3, 5)
		},
		{
				'coord1': (0, 1),
				'coord2': (2, 5)
		}
]

mypy

Es un modulo que nos permite trabajar con tipos y mostrar los errores en consola y se complementa con el modulo typing que viene en el core de python que nos permite definir tipos complejos.

Ventajas

  • Claridad y calidad en el código.
  • Devuelve los errores antes que se ejecuten.

Estuvo super interesante esta clase, aunque también medio deep. Dejo mis apuntes por si alguien les quiere echa un ojo
Apuntes de tipado

El módulo mypy sirve para detectar errores de tipado débil que puede haber cuando se hace a Python un lenguaje de tipado estático.

El tipado estático nos aporta claridad y calidad al código. Con el tipado estático, los errores se retornaran antes de que el programa se ejecute.

Personalmente me gustó mucho esta clase, no sabía qué esto se podía hacer, pero estas son las cosas por la que me gusta tanto Python, es un lenguaje super flexible.

Deberían generar un libro de consulta con toda esta información… para no tener que estar buscando dentro de los videos… Por favor que tarea tediosa…

Parece que tendre que volver a repasar los apuntes de los cursos básico e intermedio de Python esta clase si venia cargada con mucha nueva información pero me gusto esta clase interesante aprender más sobre Python

myvar:<type> #convert static typing python3.6
def myfucnt(myvar:<type>) -> <type> #indica el tipo que retorna

Ahora comprendo el por qué a veces al auto-completar funciones, el VS colocaba un -> None después de las funciones.

Wow!!! Vine por cobre y encontré oro puro!

Entendido y a poner en práctica.

Woooww ,este curso es una locura, quiero terminarlo todo hoy mismo!!!

Excelente clase magistral, me llevo mucho que aprender y aplicar el mi mundo de la programación . Muchos éxitos a todos

Algunas capturas que pueden ayudar:

Excelente, se aprenden cosas nuevas e importantes

Este curso realmente me esta enriqueciendo mis conocimientos

Se parece mucho a programar en c++ 😮.

Deberia existir alguna manera para uno citar los puntos del video sobre el que tiene preguntas o comentarios, eso seria muy util.

ufff, esto esta genial. y esta brutal.

He programado en C++, Java😬, Processing(Java) y definitivamente me encanta Python 💙💛🐍, tiene muchas cosas divertidas

Para complementar esta ruta de python les comparto las features de la versión 3.10 que trae cosas muy divertidas e interesantes como zip(), match(switch case) , typing donde pueden profundizar sobre estos temas. https://realpython.com/python310-new-features/#type-unions-aliases-and-guards

Me gusta que Python lo haya implementado en su core, los que venimos de JavaScript y más específicamente de TypeScript sabemos que bonito puede ser el static typing 😄

Esta sintaxis me recuerda a Swift.

Esta sintaxis me recuerda mucho a chichar

Soy desarrollador Typescript, por necesidades laborales estoy estudiando Python y no sabia esto y me encantaaaaa!! 😃

Se agrandan los ojos y se calienta el cerebro !!!

si utilizas python antes de la version 3.6 no se podra utilizar esta tipado.

He estudiado y practicado C y C++, aprendí Java básico, aprender Python y ver lo flexible que es es alucinante pero sientes que no tienes control sobre como los datos se procesaran, es increíble aprender que puedo implementar esa rigurosidad en python

Asignar tipos a las variables de Python en funciones

Declarar variables y asignar un tipo en Python 😲

Wow esto es muy nuevo para mí!!

declarar variables como los tipos que se van a utilizar

WOW! mucha información y muy valiosa, es hora de tomar un descanso para poder seguir aprendiendo!

👾

Seria bueno un video o post explicando que trajo de nuevo Python 3.10.

Super interesante! Esto es lo que esperaba en un curso avanzado de python!

Se podira considerar que la variable “CoordinatesType” es una instancia de Coordinates.

Esta clase y la anterior son “eyes openers” en cuanto a fundamentos de lenguajes de programación.

Woooww!!! No sabía que Python también podría ser tipado.

Desde que versión de Python se puede usar el modulo typing?

modulo mypy permite mostrar los errores de tipado en consola

indica tambien el tipo de resultado que retorna una función

declaracion de variables con tipado estatico

Sabia como hacerlo con parametros de functiones, pero no sabia que tambien podiamos hacerlo con el resto de cosas, yei