Características de Python 3 que vale la pena usar

Muchos programadores comenzaron a cambiar de la segunda versión de Python a la tercera debido al hecho de que muy pronto se suspenderá el soporte para Python 2. El autor del artículo, cuya traducción publicamos, señala que la mayor parte del código Python 3 que vio, parece un código entre paréntesis, escrito en Python 2. Según él, él mismo peca algo así . Aquí da ejemplos de algunas de las excelentes funciones disponibles solo para aquellos que usan Python 3. Espera que estas funciones hagan la vida más fácil para aquellos que las conocen.



Todos los ejemplos en este artículo están escritos usando Python 3.7. La descripción de cada característica contiene información sobre la versión mínima de Python necesaria para su uso.

Cadenas de formato (3.6+)


Sin cadenas, es difícil escribir algo útil en cualquier lenguaje de programación. Pero para un trabajo efectivo con cadenas, un desarrollador necesita herramientas convenientes. Tales herramientas que le permiten operar con estructuras complejas sin perder la tranquilidad. La mayoría de los desarrolladores de Python usan el método de format :

 user = "Jane Doe" action = "buy" log_message = 'User {} has logged in and did an action {}.'.format( user, action ) print(log_message) # User Jane Doe has logged in and did an action buy. 

Python 3, junto con el método de format , admite cadenas de formato (cadenas f, cadenas f). Son una herramienta flexible para realizar diversas manipulaciones de cadenas. Así es como se ve el ejemplo anterior, reescrito usando cadenas de formato:

 user = "Jane Doe" action = "buy" log_message = f'User {user} has logged in and did an action {action}.' print(log_message) # User Jane Doe has logged in and did an action buy. 

Módulo Pathlib (3.4+)


Las cadenas de formato son una tecnología maravillosa, pero se han creado herramientas especiales para trabajar con algunas líneas, como las rutas de archivos, que simplifican enormemente su manipulación. Python 3 tiene un módulo pathlib , que es una abstracción conveniente para trabajar con rutas de archivos. Si aún no está seguro de la utilidad de este módulo para resolver sus problemas, eche un vistazo a este material.

 from pathlib import Path root = Path('post_sub_folder') print(root) # post_sub_folder path = root / 'happy_user' #    print(path.resolve()) # /home/weenkus/Workspace/Projects/DataWhatNow-Codes/how_your_python3_should_look_like/post_sub_folder/happy_user 

Anotaciones de tipo (3.5+)


¿Qué es mejor: tipeo estático o dinámico? Quizás casi todos los programadores tengan su propia respuesta a esta difícil pregunta. Dejo en manos del lector cómo tipifican exactamente sus programas. Pero creo que es bueno para todos al menos saber que Python 3 admite anotaciones de tipo .

 def sentence_has_animal(sentence: str) -> bool: return "animal" in sentence sentence_has_animal("Donald had a farm without animals") # True 

Transferencias (3.4+)


Python 3 admite, gracias a la clase Enum , un mecanismo simple para trabajar con enumeraciones . Las enumeraciones son convenientes para almacenar listas de constantes. Las constantes, de lo contrario, se dispersan aleatoriamente en el código.

 from enum import Enum, auto class Monster(Enum):   ZOMBIE = auto()   WARRIOR = auto()   BEAR = auto()  print(Monster.ZOMBIE) # Monster.ZOMBIE 

A partir de la documentación de Python 3, puede descubrir que una enumeración es una colección de nombres simbólicos (miembros) vinculados a valores únicos e inmutables. Los miembros de una lista única se pueden comparar por identidad. Las enumeraciones pueden saltarse.

 for monster in Monster:   print(monster) # Monster.ZOMBIE # Monster.WARRIOR # Monster.BEAR 

Caché LRU incorporada (3.2+)


Hoy en día, los mecanismos de almacenamiento en caché se utilizan en casi todos los sistemas de software y hardware. Python 3 simplifica enormemente el almacenamiento en caché con el decorador lru_cache , que implementa el algoritmo de almacenamiento en caché LRU ( menos utilizado recientemente ).

A continuación se muestra una función que calcula los números de Fibonacci. Esta función se ve obligada muchas veces a realizar las mismas operaciones durante las llamadas recursivas. Como resultado, resulta que su rendimiento se puede mejorar mediante el almacenamiento en caché.

 import time def fib(number: int) -> int:   if number == 0: return 0   if number == 1: return 1     return fib(number-1) + fib(number-2) start = time.time() fib(40) print(f'Duration: {time.time() - start}s') # Duration: 30.684099674224854s 

Ahora usamos lru_cache para optimizar esta función (esta técnica de optimización se llama memorización ). Como resultado, el tiempo de ejecución de una función que se midió previamente en segundos ahora se mide en nanosegundos.

 from functools import lru_cache @lru_cache(maxsize=512) def fib_memoization(number: int) -> int:   if number == 0: return 0   if number == 1: return 1     return fib_memoization(number-1) + fib_memoization(number-2) start = time.time() fib_memoization(40) print(f'Duration: {time.time() - start}s') # Duration: 6.866455078125e-05s 

Desempaquetar objetos iterables (3.0+)


Al desempaquetar objetos iterables, puede usar variables cuyos nombres estén precedidos por un asterisco. Todo lo que no cabe en otras variables entra en tales variables. Entonces, en el siguiente ejemplo, los valores primero y último de la lista formada por el comando range(5) caen en las variables head y tail . Todo lo que está entre el primer y el último valor entra en la variable del body .

 head, *body, tail = range(5) print(head, body, tail) # 0 [1, 2, 3] 4 py, filename, *cmds = "python3.7 script.py -n 5 -l 15".split() print(py) print(filename) print(cmds) # python3.7 # script.py # ['-n', '5', '-l', '15'] first, _, third, *_ = range(10) print(first, third) # 0 2 

Clases de datos (3.7+)


Python 3 introdujo clases de datos . Le dan al programador mucha libertad de acción. Se pueden usar para reducir la cantidad de código repetitivo. El hecho es que el decorador de dataclass genera automáticamente métodos especiales, como __init__() y __repr__() . En el texto oficial de la propuesta correspondiente , se describen como "tuplas nombradas mutables con valores predeterminados". Aquí hay un ejemplo de dataclass crear una clase sin usar el decorador de clase de dataclass :

 class Armor:     def __init__(self, armor: float, description: str, level: int = 1):       self.armor = armor       self.level = level       self.description = description                  def power(self) -> float:       return self.armor * self.level  armor = Armor(5.2, "Common armor.", 2) armor.power() # 10.4 print(armor) # <__main__.Armor object at 0x7fc4800e2cf8> 

Aquí es lo mismo, pero ya escrito usando dataclass :

 from dataclasses import dataclass @dataclass class Armor:   armor: float   description: str   level: int = 1     def power(self) -> float:       return self.armor * self.level  armor = Armor(5.2, "Common armor.", 2) armor.power() # 10.4 print(armor) # Armor(armor=5.2, description='Common armor.', level=2) 

Compatibilidad con carpetas de paquetes sin archivo __init__.py (3.3+)


Una forma de estructurar el código de Python es usar paquetes (los paquetes se colocan en carpetas que contienen el archivo __init__.py ). Aquí hay un ejemplo de la documentación oficial:

 sound/                                 __init__.py                 sound     formats/                                   __init__.py             wavread.py             wavwrite.py             aiffread.py             aiffwrite.py             auread.py             auwrite.py             ...     effects/                                  __init__.py             echo.py             surround.py             reverse.py             ...     filters/                                 __init__.py             equalizer.py             vocoder.py             karaoke.py             ... 

Al usar Python 2, cada una de las carpetas mencionadas en el ejemplo debe tener un archivo __init__.py . Gracias a este archivo, la carpeta se percibe como un paquete de Python. En Python 3, con el advenimiento de la característica Paquetes de espacio de nombres implícitos , carpetas como estas ya no son necesarias.

 sound/                                 __init__.py                 sound     formats/                                   wavread.py             wavwrite.py             aiffread.py             aiffwrite.py             auread.py             auwrite.py             ...     effects/                                  echo.py             surround.py             reverse.py             ...     filters/                                 equalizer.py             vocoder.py             karaoke.py             ... 

Cabe señalar que, de hecho, no todo es tan simple. Es decir, de acuerdo con esta especificación oficial, el archivo __init__.py todavía es necesario para los paquetes regulares. Si lo elimina de la carpeta, el paquete se convierte en el denominado paquete de espacio de nombres , al que se aplican restricciones adicionales.

Resumen


No todas las características interesantes de Python 3 están cubiertas en este artículo, pero esperamos que encuentre algo útil aquí. Se puede encontrar código de muestra en este repositorio.

Estimados lectores! ¿Qué características de Python 3 agregarías a la lista aquí?

Source: https://habr.com/ru/post/452564/


All Articles