Python, continua con su desarrollo y aunque en la versión 2.7 ya no tiene grandes cambios si que lo tiene en la versión 3, en esta ocasión la versión 3.7 que incluye una cuantas cositas que si que valen la pena mencionar.
[amazon_link asins=’1977921752,1783551313,B018T6ZVPK’ template=’ProductCarousel’ store=’launocom-20′ marketplace=’MX’ link_id=’db881ca5-9128-11e8-8132-31ef3fc14c8a’]
Breakpoints ahora están dentro de builtins.
Cuando queremos depurar código y no estamos usando un IDE o queremos hacerlo “a manita” recurrimos a pdb
y set_trace()
, que tenemos que importarlo y después invocarlo, es fácil pero no llega a ser tan práctico como print()
, por eso muchos prefieren llenar de print
su código.
Ahora con breakpoints es fácil crear un punto donde la ejecución del programa se detenga para la depuración, sin necesidad de hacer un import primero y después, una vez que hemos terminado de depurar, quitarlo.
def adivina(numero): adivinado = input("advina el numero") breakpoint() if numero == adivinado: return "Exito!" return "Nope"
El resultado es básicamente igual que si llamáramos pdb.set_trace()
pero de nuevo, sin importar nada ni quitar mas que el breakpoint.
Anotaciones y tipado de datos
Python se ha notado por mucho tiempo en que las funciones/métodos no tienen un tipado duro, bueno, sigue siendo, pero si quieres hacer un tipado ahora lo puedes hacer. Para esto al definir tus parámetros pondrás dos puntos y seguido el tipo de dato que se espera.
def adivina(numero: int):
Adicional a esto, puedes decir que tipo de valor devolverá la función/método, para esto, después de la definición de tu función, antes de los dos puntos, pones un guion y mayor que ->
y el tipo de dato que se devolverá.
def adivina(numero: int) -> str:
Como podemos ver, advina
ahora indica que devolverá una cadena. Esto nos ayudará en los IDEs que detecten este tipo de errores directamente mientras escribimos, evitándonos problemas en tiempo de ejecución.
Que pasa si el tipo de dato es el mismo de la clase ?.
La solución son anotaciones, veamos este ejemplo:
class User: def __init__(self, user: str, prev_user: User) -> None:
En este ejemplo no podemos indicar que el tipo de dato de es
User
puesto que no está definido aún. Para esto tendremos que importar annotations
de __future__
. Esto se tiene que hacer así para mantener la compatibilidad a codigo escrito previamente.
from __future__ import annotations class User: def __init__(self, user: str, prev_user: User) -> None:
Nanosegundos en Time
time
tiene nuevas funciones, ahora cada función de time
tiene su función correspondiente en nanosegundos, por ejemplo, time.time()
tiene su correspondiente time.time_ns()
que agrega la resolución de nanosegundos.
Mas rápido
Hablando de tiempos, Python es mas rápido, las optimizaciones son a bajo nivel por lo que nose ahondara aquí, pero en general, es 10% mas rápido en Linux, 30% mas rápido en macOS y en términos generales las funciones serán un 20% mas rápidas.
Dataclases
Es común que escribamos el inicializador solo para asignar unas variables a la clase:
class User: def __init__(self, name: str, age: int) -> None: self.name = name self.age = age def is_adult(self) -> bool: return self.age > 18 u = User("Marco", 34) u.is_adult() True
Dataclases nos ahorra este trabajo, para esto tendremos que decorar la clase con @dataclass
@dataclass class User: name: str age: int def is_adult(self) -> bool: return self.age > 18 u = User("Marco", 34) u.is_adult() True
[amazon_link asins=’B00D2XIU9A,B000MQAPPC,B019PHO23E’ template=’ProductCarousel’ store=’launocom-20′ marketplace=’MX’ link_id=’65954cfe-9129-11e8-be3e-47fbd44d5426′]
Otros cambios:
- Los diccionarios ahora respetan el orden en que fueron insertados los datos, por lo tanto un diccionario remplazará en casi todos los casos a
collections.OrderedDict
. - Documentation en Frances, Coreano y Japonés
- Control del contenido del módulo puesto que
__getattr__
ahora puede ser definido a nivel de módulo. - Un nuevo modo developer para cPython.
- Los archivos .pyc son deterministicos, es decir, cada ejecución creará exactamente el mismo .pyc byte por byte.
Mas información en las notas de liberación de Python 3.7