Categorías
Python

Tipo de Python Comprobación (Guía)

 

Tabla de Contenidos

  • La morsa en la habitación: Asignación Expresiones
  • posicional argumentos de sólo
  • Tipos más preciso
  • más simple de depuración con dirección f-Strings
  • El Consejo Python
  • Otros Featuresimportlib.metadataNew bastante fresco y mejorado matemáticas y estadísticas FunctionsWarnings Sobre SyntaxOptimizations peligrosas
  • importlib.metadata
  • nueva y mejorada de matemáticas y estadística Advertencias
  • Sobre peligroso sintaxis
  • optimizaciones
  • Por lo tanto, debe actualizar a Python 3.8?
  • importlib.metadata
  • nueva y mejorada de matemáticas y estadística
  • advertencias sobre Dangerous Sintaxis
  • optimizaciones

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del Real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: nuevas características Cool en Python 3.8

La nueva versión de Python está disponible! Python 3.8 ha estado disponible en las versiones beta desde el verano, pero el 14 de octubre, 2019 primera versión oficial está listo. Ahora, todos podemos empezar a jugar con las nuevas características y funcionamiento de las últimas mejoras.

Lo que hace Python 3.8 traer a la mesa? La documentación da una buena visión general de las nuevas características. Sin embargo, este artículo voy a entrar más en profundidad sobre algunos de los cambios más grandes, y le mostrará cómo se puede aprovechar de Python 3.8.

En este artículo, usted aprenderá acerca de:

  • El uso de expresiones de asignación para simplificar un poco de código construye
  • hace cumplir posicional-únicos argumentos en sus propias funciones
  • especificando el tipo más precisa consejos
  • Usando F-cuerdas de más simple depuración

Con unas pocas excepciones, Python 3.8 contiene muchas pequeñas mejoras respecto a las versiones anteriores. Hacia el final del artículo, verá muchos de estos cambios menos que llaman la atención, así como una discusión sobre algunas de las optimizaciones que hacen Python 3.8 más rápido que sus predecesores. Por último, obtendrá algunos consejos acerca de la actualización a la nueva versión. Bono

gratuito: Haga clic aquí para obtener acceso a un capítulo de trucos Python: El libro que te muestra las mejores prácticas de Python con ejemplos sencillos puede aplicar instantáneamente a escribir código más bonito + Pythonic.

La morsa en la habitación: Asignación Expresiones

El cambio más grande en Python 3.8 es la introducción de expresiones de asignación . Se escriben utilizando una nueva notación (: =). Este operador es a menudo llamado el morsa operador ya que se asemeja a los ojos y los colmillos de una morsa en su lado.

expresiones de asignación le permiten asignar y devolver un valor en la misma expresión. Por ejemplo, si desea asignar a una variable e imprimir su valor, entonces lo hace normalmente algo como esto:

>>> walrus = False
>>> print(walrus)
False

En Python 3.8, se le permite combinar estas dos afirmaciones en uno, usando el operador de morsa:

>>> print(walrus := True)
True

la expresión de asignación le permite asignar Fiel a morsa, e imprimir inmediatamente el valor. Pero hay que tener en cuenta que el operador no morsa no hacer cualquier cosa que no es posible sin él. Sólo tiene ciertas construcciones más conveniente, ya veces se puede comunicar la intención de su código con mayor claridad.

Un patrón que muestra algunos de los puntos fuertes del operador de la morsa es un bucle while en el que se tiene que inicializar y actualizar una variable. Por ejemplo, el código siguiente pregunta al usuario para la entrada hasta que se escriba quit:

inputs = list()
current = input("Write something: ")
while current != "quit":
inputs.append(current)
current = input("Write something: ")

Este código es menos que ideal. Estás repitiendo la instrucción de entrada (), y de alguna manera es necesario añadir a la lista actual antes preguntar al usuario por ello. Una mejor solución es la creación de un infinito mientras bucle y descanso utilizar para detener el bucle:

inputs = list()
while True:
current = input("Write something: ")
if current == "quit":
break
inputs.append(current)

Este código es equivalente a la anterior, pero evita la repetición y de alguna manera mantiene las líneas en un orden más lógico. Si utiliza una expresión de asignación, puede simplificar aún más este bucle:

inputs = list()
while (current := input("Write something: ")) != "quit":
inputs.append(current)

Esto mueve la prueba de retorno a la línea de tiempo, donde tiene que estar. Sin embargo, ahora hay varias cosas que suceden en esa línea, así que lleva un poco más de esfuerzo para leerlo correctamente. Utilizar su mejor juicio acerca de cuando el operador morsa ayuda a que el código sea más legible.

PEP 572 describe todos los detalles de expresiones de asignación, entre ellas algunas de las razones para su introducción en el lenguaje, así como varios ejemplos de cómo se puede utilizar el operador de morsa.

posicional argumentos de sólo

la incorporada en función float () se puede utilizar para convertir cadenas de texto y números a los objetos flotantes. Consideremos el siguiente ejemplo:

>>> float("3.8")
3.8

>>> help(float)
class float(object)
| float(x=0, /)
|
| Convert a string or number to a floating point number, if possible.

[...]

mira de cerca el firma del flotador (). Note la barra (/) después del parámetro. Qué significa eso?

Nota: Para una discusión en profundidad sobre el / la notación, ver PEP 457 – Notación de los parámetros de sólo posicionales.

Resulta que mientras que el único parámetro de flotador () se llama x, que no está permitido el uso de su nombre:

>>> float(x="3.8")
Traceback (most recent call last):
File "", line 1, in
TypeError: float() takes no keyword arguments

Al usar flotador () sólo se permite para especificar los argumentos de la posición, no por palabra clave . Antes de Python 3.8, tales posicionales sólo para argumentos eran sólo es posible para las funciones incorporadas. No había ninguna manera fácil para especificar que los argumentos deberían ser posicional de sólo en sus propias funciones:

>>> def incr(x):
... return x + 1
...
>>> incr(3.8)
4.8

>>> incr(x=3.8)
4.8

Es posible simular argumentos posicionales de sólo usando * args, pero esto es menos flexible, menos legible, y las fuerzas usted para implementar su propio análisis argumento. En Python 3.8, puede usar / para indicar que todos los argumentos que se le deben especificarse por posición. Puede volver a escribir incr () para aceptar sólo argumentos posicionales:

>>> def incr(x, /):
... return x + 1
...
>>> incr(3.8)
4.8

>>> incr(x=3.8)
Traceback (most recent call last):
File "", line 1, in
TypeError: incr() got some positional-only arguments passed as
keyword arguments: 'x'

Al añadir / después de x, se especifica que x es un posicional-único argumento. Se pueden combinar con los argumentos regulares posicional de sólo mediante la colocación de los argumentos regulares después de la barra:

>>> def greet(name, /, greeting="Hello"):
... return f"{greeting}, {name}"
...
>>> greet("Łukasz")
'Hello, Łukasz'

>>> greet("Łukasz", greeting="Awesome job")
'Awesome job, Łukasz'

>>> greet(name="Łukasz", greeting="Awesome job")
Traceback (most recent call last):
File "", line 1, in
TypeError: greet() got some positional-only arguments passed as
keyword arguments: 'name'

En greet (), la barra se coloca entre el nombre y el saludo. Este nombre significa que es un argumento posicional-solamente, mientras que el saludo es un argumento habitual que se puede pasar ya sea por la posición o por palabra clave.

A primera vista, los argumentos posicionales sólo puede parecer un poco limitante y contraria a la mantra de Python sobre la importancia de la lectura. Es probable que encuentre que no hay una gran cantidad de ocasiones en las posicional argumentos de sólo mejoran su código.

Sin embargo, en las circunstancias adecuadas, posicional-únicos argumentos puede darle cierta flexibilidad cuando se está diseñando funciones. En primer lugar, los argumentos posicionales sólo tiene sentido cuando se tiene argumentos que tienen un orden natural, pero son difíciles de dar buena, nombres descriptivos a.

Otra posible ventaja de utilizar argumentos posicionales sólo es que se puede refactorizar más fácilmente sus funciones. En particular, se puede cambiar el nombre de los parámetros sin tener que preocuparse de que otro código depende de esos nombres.

posicional-únicos argumentos complementan muy bien palabra clave sólo argumentos. En cualquier versión de Python 3, puede especificar palabra clave sólo argumentos que utilizan la estrella (*). Cualquier argumento después * debe especificarse utilizando una palabra clave:

>>> def to_fahrenheit(*, celsius):
... return 32 + celsius * 9 / 5
...
>>> to_fahrenheit(40)
Traceback (most recent call last):
File "", line 1, in
TypeError: to_fahrenheit() takes 0 positional arguments but 1 was given

>>> to_fahrenheit(celsius=40)
104.0

centígrados es un argumento de palabra clave-solamente, así que Python lanza un error si se intenta especificar que basándose en la posición, sin la palabra clave.

Puede combinar posicional de sólo regular, y los argumentos de palabras clave sólo, especificando en este orden separados por / y *. En el siguiente ejemplo, el texto es un posicional-único argumento, la frontera es un argumento regular con un valor por defecto, y el ancho es un argumento de palabra clave sólo con un valor por defecto:

>>> def headline(text, /, border="♦", *, width=50):
... return f" {text} ".center(width, border)
...

Dado que el texto es de sólo posicional, no se puede utilizar el texto de palabras clave: frontera

>>> headline("Positional-only Arguments")
'♦♦♦♦♦♦♦♦♦♦♦ Positional-only Arguments ♦♦♦♦♦♦♦♦♦♦♦♦'

>>> headline(text="This doesn't work!")
Traceback (most recent call last):
File "", line 1, in
TypeError: headline() got some positional-only arguments passed as
keyword arguments: 'text'

, por el contrario, se puede especificar con y sin la palabra clave:

>>> headline("Python 3.8", "=")
'=================== Python 3.8 ==================='

>>> headline("Real Python", border=":")
':::::::::::::::::: Real Python :::::::::::::::::::'

por último, el ancho debe ser especificado usando la palabra clave:

>>> headline("Python", " ", width=38)
' Python '

>>> headline("Python", " ", 38)
Traceback (most recent call last):
File "", line 1, in
TypeError: headline() takes from 1 to 2 positional arguments
but 3 were given

puede leer más sobre posicional-únicos argumentos en PEP 570.

Tipos más preciso sistema de tipificación de

Python es bastante maduro en este punto. Sin embargo, en Python 3.8, algunas nuevas características se han añadido a la tipificación para permitir la tipificación más precisa: Objetos diccionarios tipos

  • literales
  • con tipo
  • final
  • Protocolos

Python soporta opcional consejos de tipo , típicamente como anotaciones en su código:

def double(number: float) -> float:
return 2 * number

en este ejemplo, se dice que el número debe ser una función doble () debe devolver un flotador, así flotador y. Sin embargo, Python trata estas anotaciones como insinúa . Ellos no se hacen cumplir en tiempo de ejecución:

>>> double(3.14)
6.28

>>> double("I'm not a float")
"I'm not a floatI'm not a float"

doble () acepta felizmente «No soy un flotador» como un argumento, a pesar de que eso no es un flotador. Hay bibliotecas que pueden utilizar tipos en tiempo de ejecución, pero ese no es el principal caso de uso para el sistema de tipo de Python.

En cambio, de tipo indicios permiten a las damas de tipo estático para hacer la comprobación de tipos de su código Python, sin ejecutar las secuencias de comandos. Esto es una reminiscencia de los compiladores de la captura de errores de tipo en otros lenguajes como Java, Rust, y Crystal. Además, forma de consejos actúan como documentación de su código, por lo que es más fácil de leer, así como la mejora de la función de autocompletar en su IDE.

Nota: Hay varias damas de tipo estático disponibles, incluyendo Pyright, Pytype y Pira. En este artículo, vamos a usar Mypy. Puede instalar Mypy de PyPI usando pip:

$ python -m pip install mypy

En cierto sentido, Mypy es la implementación de referencia de un comprobador de tipos para Python, y está siendo desarrollado en Dropbox bajo la dirección de Jukka Lehtasalo. El creador de Python, Guido van Rossum, es parte del equipo Mypy.

Puede encontrar más información acerca de las sugerencias de tipo en Python en el PEP original de 484, así como en Pitón Tipo Comprobación (Guía).

Hay cuatro nuevos PEP sobre la comprobación de tipos que han sido aceptados e incluidos en Python 3.8. Verá ejemplos breves de cada uno de éstos.

PEP 586 introducir el tipo literal . literal es un poco especial, ya que representa uno o varios valores específicos. Un caso de uso de literal es ser capaz de añadir precisión tipos, cuando se utilizan los argumentos de cadena para describir el comportamiento específico. Consideremos el siguiente ejemplo:

# draw_line.py

def draw_line(direction: str) -> None:
if direction == "horizontal":
... # Draw horizontal line

elif direction == "vertical":
... # Draw vertical line

else:
raise ValueError(f"invalid direction {direction!r}")

draw_line("up")

El programa pasará el tipo de electricidad estática, a pesar de que «arriba» es una dirección válida. El tipo de corrector sólo comprueba que «arriba» es una cadena. En este caso, sería más preciso decir que la dirección debe ser la cadena literal «horizontal» o la cadena literal «vertical». El uso literal, puede hacer exactamente eso:

# draw_line.py

from typing import Literal

def draw_line(direction: Literal["horizontal", "vertical"]) -> None:
if direction == "horizontal":
... # Draw horizontal line

elif direction == "vertical":
... # Draw vertical line

else:
raise ValueError(f"invalid direction {direction!r}")

draw_line("up")

Al exponer los valores permitidos de dirección para el comprobador de tipos, ahora puede ser advertido acerca del error:

$ mypy draw_line.py
draw_line.py:15: error:
Argument 1 to "draw_line" has incompatible type "Literal['up']";
expected "Union[Literal['horizontal'], Literal['vertical']]"
Found 1 error in 1 file (checked 1 source file)

La sintaxis básica es literal []. Por ejemplo, literal [38] Representa el valor literal 38. Usted puede expresar uno de varios valores literales utilizando Unión:

Union[Literal["horizontal"], Literal["vertical"]]

Puesto que esto es un caso de uso bastante común, puede (y probablemente debería) usar la notación más simple literal [» horizontal», «vertical»] en su lugar. Ya ha utilizado estos últimos tipos añadidos a la draw_line (). Si se fijan bien en la salida de Mypy anterior, se puede ver que traduce la notación más simple a la notación Unión internamente.

Hay casos en los que el tipo del valor de retorno de una función depende de los argumentos de entrada. Un ejemplo es abierto (), que puede devolver una cadena de texto o una matriz de bytes en función del valor de modo. Esto puede ser manejado por sobrecarga.

El siguiente ejemplo muestra el esqueleto de un calculador que puede devolver la respuesta, ya sea como números regulares (38), o como números romanos (XXXVIII):

# calculator.py

from typing import Union

ARABIC_TO_ROMAN = [(1000, "M"), (900, "CM"), (500, "D"), (400, "CD"),
(100, "C"), (90, "XC"), (50, "L"), (40, "XL"),
(10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I")]

def _convert_to_roman_numeral(number: int) -> str:
"""Convert number to a roman numeral string"""
result = list()
for arabic, roman in ARABIC_TO_ROMAN:
count, number = divmod(number, arabic)
result.append(roman * count)
return "".join(result)

def add(num_1: int, num_2: int, to_roman: bool = True) -> Union[str, int]:
"""Add two numbers"""
result = num_1 + num_2

if to_roman:
return _convert_to_roman_numeral(result)
else:
return result

el código tiene los indicios tipo correcto: el resultado de add () se ser str o int. Sin embargo, a menudo este código será llamada con un Verdadero o Falso literal como el valor de to_roman en el que caso de que quiera el tipo de corrector para inferir con exactitud si se devuelve str o int. Esto se puede hacer usando literal junto con @overload:

# calculator.py

from typing import Literal, overload, Union

ARABIC_TO_ROMAN = [(1000, "M"), (900, "CM"), (500, "D"), (400, "CD"),
(100, "C"), (90, "XC"), (50, "L"), (40, "XL"),
(10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I")]

def _convert_to_roman_numeral(number: int) -> str:
"""Convert number to a roman numeral string"""
result = list()
for arabic, roman in ARABIC_TO_ROMAN:
count, number = divmod(number, arabic)
result.append(roman * count)
return "".join(result)

@overload
def add(num_1: int, num_2: int, to_roman: Literal[True]) -> str: ...
@overload
def add(num_1: int, num_2: int, to_roman: Literal[False]) -> int: ...

def add(num_1: int, num_2: int, to_roman: bool = True) -> Union[str, int]:
"""Add two numbers"""
result = num_1 + num_2

if to_roman:
return _convert_to_roman_numeral(result)
else:
return result

El añadió firmas @overload ayudarán a su tipo de corrector str inferir o int dependiendo de los valores literales de to_roman. Tenga en cuenta que los puntos suspensivos (…) son una parte literal del código. Se destacan en el cuerpo de la función de las firmas sobrecargados.

Como complemento a literal, PEP 591 introduce final . Este calificador especifica que una variable o atributo no deben ser reasignados, redefinidas o anular. El siguiente es un error de escritura:

from typing import Final

ID: Final = 1

...

ID += 1

Mypy destacará el ID de línea + = 1, y la nota de que no se puede asignar a nombre final «ID». Esto le da una forma de asegurar que las constantes en su código nunca cambian su valor.

Además, también hay una @final decorador que se puede aplicar a las clases y métodos. Las clases decoradas con @final no pueden tener subclases, mientras @final métodos no puede ser anulado por subclases: bandera voluntad

from typing import final

@final
class Base:
...

class Sub(Base):
...

Mypy este ejemplo con el mensaje de error No se puede heredar de la clase final «base». Para obtener más información sobre Final y @final, ver PEP 591.

La tercera PEP permitiendo toques tipo más específico es PEP 589, que introduce TypedDict . Esto se puede utilizar para especificar los tipos de claves y valores en un diccionario utilizando una notación que es similar a la NamedTuple con tipo.

Tradicionalmente, los diccionarios se han anotado utilizando Dict. El problema es que esto sólo permite un tipo de las llaves y un tipo de los valores, a menudo conduce a las anotaciones como Dict [str, Cualquier]. Como ejemplo, considere un diccionario que registra información sobre las versiones de Python:

py38 = {"version": "3.8", "release_year": 2019}

El valor que corresponde a la versión es una cadena, mientras que RELEASE_YEAR es un entero. Esto no se puede representar con precisión utilizando Dict. Con el nuevo TypedDict, puede hacer lo siguiente:

from typing import TypedDict

class PythonVersion(TypedDict):
version: str
release_year: int

py38 = PythonVersion(version="3.8", release_year=2019)

El tipo de corrector será entonces capaz de inferir que py38 [ «versión»] tiene un tipo str, mientras py38 [ «RELEASE_YEAR»] es un int. En tiempo de ejecución, un TypedDict es un diccionario regular, y consejos de tipo se tienen en cuenta como de costumbre. También puede utilizar TypedDict puramente como una anotación:

py38: PythonVersion = {"version": "3.8", "release_year": 2019}

Mypy le permitirá saber si alguno de los valores tiene el tipo incorrecto, o si se utiliza una clave que no se ha declarado. Ver PEP 589 para más ejemplos.

Mypy ha apoyado Protocolos por un tiempo ya. Sin embargo, la aceptación oficial única fue en mayo del 2019.

Protocolos

son una manera de formalizar el apoyo de Python para la tipificación de pato:

Cuando veo un pájaro que camina como un pato y nada como un pato y grazna como un pato, que llamo pájaro que un pato. (Fuente)

escribiendo pato le permite, por ejemplo, leer .name en cualquier objeto que tiene un atributo .name, sin realmente preocuparse por el tipo de objeto. Puede parecer contrario a la intuición para el sistema de tipificación para apoyar esto. A través de subtipos estructural, todavía es posible dar sentido a la tipificación de pato.

Por ejemplo, puede definir un protocolo llamado con nombre que puede identificar todos los objetos con un atributo .name:

from typing import Protocol

class Named(Protocol):
name: str

def greet(obj: Named) -> None:
print(f"Hi {obj.name}")

Aquí, greet () toma cualquier objeto, siempre y cuando se define un atributo .name. Ver PEP 544 y la documentación Mypy para obtener más información acerca de los protocolos.

más simple depuración con F-Strings

f-cuerdas se introdujeron en Python 3.6, y han llegado a ser muy popular. Ellos podrían ser la razón más común para Python únicamente librerías que se admite en la versión 3.6 y posteriores. Un F-cadena es un literal de cadena con formato. Se puede reconocer por el líder de f:

>>> style = "formatted"
>>> f"This is a {style} string"
'This is a formatted string'

Cuando se utiliza F-strings, puede encerrar variables y expresiones, incluso dentro de llaves. A continuación, se evalúan en tiempo de ejecución y se incluyen en la cadena. Puede tener varias expresiones en una f-string:

>>> import math
>>> r = 3.6

>>> f"A circle with radius {r} has area {math.pi * r * r:.2f}"
'A circle with radius 3.6 has area 40.72'

En la última expresión, math.pi {* r * r: .2f}, también puede usar un especificador de formato. especificadores de formato se separan de las expresiones con un colon.

.2f significa que el área está formateado como un número de coma flotante con 2 decimales. Los especificadores de formato son los mismos que para .formato (). Consulte la documentación oficial para una lista completa de los especificadores de formato permitidos.

En Python 3.8, puede utilizar expresiones de asignación dentro de f-cuerdas. Sólo asegúrese de rodear la expresión de asignación con paréntesis:

>>> import math
>>> r = 3.8

>>> f"Diameter {(diam := 2 * r)} gives circumference {math.pi * diam:.2f}"
'Diameter 7.6 gives circumference 23.88'

Sin embargo, la verdadera f-noticias en Python 3.8 es el nuevo especificador de depuración. Ahora puede agregar = al final de una expresión, y se imprimirá tanto la expresión y su valor:

>>> python = 3.8
>>> f"{python=}"
'python=3.8'

Se trata de un corto parte, que por lo general será más útil cuando se trabaja de forma interactiva o la adición de instrucciones de impresión para depurar la secuencia de comandos . En versiones anteriores de Python, lo necesario para explicar la variable o expresión dos veces para obtener la misma información:

>>> python = 3.7
>>> f"python={python}"
'python=3.7'

Puede añadir espacios alrededor =, y especificadores de formato utilización como de costumbre:

>>> name = "Eric"
>>> f"{name = }"
"name = 'Eric'"

>>> f"{name = :>10}"
'name = Eric'

El > 10 especificador de formato dice que el nombre debe ser alineado a la derecha dentro de una cadena de 10 caracteres. = Obras para expresiones más complejas, así:

>>> f"{name.upper()[::-1] = }"
"name.upper()[::-1] = 'CIRE'"

Para obtener más información sobre F-strings, ver de Python 3 f-Strings: Una Mejora de formato de cadenas Sintaxis (Guía). Dirección

El Consejo Python

Técnicamente, la gobernabilidad de Python no es una característica del lenguaje. Sin embargo, Python 3.8 es la primera versión de Python no desarrollado bajo la dictadura benévola de Guido van Rossum. El lenguaje Python está ahora gobernado por un consejo de dirección que consta de cinco desarrolladores principales:

  • Barry Varsovia
  • Brett cañón
  • Carol Dispuesto
  • Guido van Rossum
  • Nick Coghlan

El camino hacia el nuevo modelo de gobierno para Python fue un estudio interesante en la auto-organización. Guido van Rossum creó Python a principios de 1990, y ha sido apodado cariñosamente Dictador Benevolente de Python para la Vida (BDFL). A través de los años, se hicieron cada vez más decisiones sobre el lenguaje Python a través de propuestas de mejora de Python (PEP). Aún así, Guido tenía oficialmente la última palabra sobre cualquier nueva característica del lenguaje.

Después de un largo y prolongado debate acerca de las expresiones de asignación, Guido anunció en julio de 2018 que se retiraba de su papel como BDFL (esta vez de verdad). El propósito no nombró un sucesor. En lugar de ello, le pidió al equipo de desarrolladores del núcleo de encontrar la manera de Python debe regirse en el futuro.

Por suerte, el proceso PEP ya estaba bien establecida, por lo que era natural utilizar PEP para discutir y decidir sobre un nuevo modelo de gobierno. A través de la caída de 2018, se propusieron varios modelos, incluyendo la elección de un nuevo BDFL (rebautizada las decisiones del árbitro Clemente Influir oficial: la GUIDO), o el traslado a un modelo comunitario basado en el consenso y la votación, sin dirección centralizada. En diciembre de 2018, el modelo de los consejos de dirección fue elegido después de una votación entre los desarrolladores del núcleo.

El consejo de dirección se compone de cinco miembros de la comunidad de Python, como se indica anteriormente. Habrá una elección para un nuevo consejo de dirección después de cada lanzamiento importante de Python. En otras palabras, habrá una elección tras la publicación de Python 3.8.

pesar de que es una elección abierta, se espera que la mayoría, si no todos, del consejo de dirección inaugural será reelegido. El consejo de dirección tiene amplio poder para tomar decisiones sobre el lenguaje Python, pero debe esforzarse por ejercer esos poderes tan poco como sea posible.

Usted puede leer todo sobre el nuevo modelo de gobierno en el PEP 13, mientras que el proceso de decidir sobre el nuevo modelo se describe en PEP 8000. Para obtener más información, consulte la PyCon 2019 Keynote, y escuchar a Brett cañón en charla Python a mí y en el podcast de cambios. Puede seguir las actualizaciones del consejo de dirección en GitHub.

Otras características Pretty Cool

Hasta ahora, usted ha visto los titulares de las noticias con respecto a lo que hay de nuevo en Python 3.8. Sin embargo, hay muchos otros cambios que son también muy bueno. En esta sección, obtendrá un rápido vistazo a algunos de ellos.

importlib.metadata

Hay un nuevo módulo disponible en la biblioteca estándar en Python 3.8: importlib.metadata. A través de este módulo, se puede acceder a información sobre los paquetes instalados en su instalación de Python. Junto con su compañero de módulo, importlib.resources, importlib.metadata mejora en la funcionalidad de los pkg_resources mayores.

A modo de ejemplo, se puede obtener alguna información acerca de pepita:

>>> from importlib import metadata
>>> metadata.version("pip")
'19.2.3'

>>> pip_metadata = metadata.metadata("pip")
>>> list(pip_metadata)
['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author',
'Author-email', 'License', 'Keywords', 'Platform', 'Classifier',
'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier',
'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier',
'Classifier', 'Classifier', 'Requires-Python']

>>> pip_metadata["Home-page"]
'https://pip.pypa.io/'

>>> pip_metadata["Requires-Python"]
'>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*'

>>> len(metadata.files("pip"))
668

La versión instalada de pip es 19.2.3. metadatos () da acceso a la mayor parte de la información que se puede ver en PyPI. Por ejemplo, puede ver que esta versión del PIP requiere ya sea Python 2.7, o Python 3.5 o superior. Con archivos (), se obtiene una lista de todos los archivos que componen el paquete PIP. En este caso, hay cerca de 700 archivos.

archivos () devuelve una lista de objetos de trazado. Éstos le dan una forma conveniente de buscar en el código fuente de un paquete, usando read_text (). El siguiente ejemplo imprime __init__.py del paquete realpython-lector:

>>> [p for p in metadata.files("realpython-reader") if p.suffix == ".py"]
[PackagePath('reader/__init__.py'), PackagePath('reader/__main__.py'),
PackagePath('reader/feed.py'), PackagePath('reader/viewer.py')]

>>> init_path = _[0] # Underscore access last returned value in the REPL
>>> print(init_path.read_text())
"""Real Python feed reader

Import the `feed` module to work with the Real Python feed:

>>> from reader import feed
>>> feed.get_titles()
['Logging in Python', 'The Best Python Books', ...]

See https://github.com/realpython/reader/ for more information
"""

# Version of realpython-reader package
__version__ = "1.0.0"

...

Se pueden ingresar las dependencias de paquetes de acceso también:

>>> metadata.requires("realpython-reader")
['feedparser', 'html2text', 'importlib-resources', 'typing']

requiere () enumera las dependencias de un paquete. Se puede ver que realpython-lector, por ejemplo, utiliza feedparser en el fondo de leer y analizar un canal de artículos.

Hay una backport de importlib.metadata disponibles en PyPI que funciona en versiones anteriores de Python. Se puede instalar usando pip:

$ python -m pip install importlib-metadata

puede caer de nuevo sobre el uso del backport PyPI en el código de la siguiente manera:

try:
from importlib import metadata
except ImportError:
import importlib_metadata as metadata

...

Véase la documentación para obtener más información sobre importlib.metadata

nueva y mejorada de matemáticas y estadísticas Funciones

Python 3.8 trae muchas mejoras en los paquetes de bibliotecas estándar existentes y módulos. matemáticas en la biblioteca estándar tiene algunas nuevas funciones. math.prod () funciona de manera similar a la incorporada en suma (), pero para los productos multiplicativos:

>>> import math
>>> math.prod((2, 8, 7, 7))
784

>>> 2 * 8 * 7 * 7
784

Las dos afirmaciones son equivalentes. prod () será más fácil de usar cuando ya tiene los factores almacenados en un iterable.

Otra nueva función se math.isqrt (). Puede utilizar isqrt () para encontrar la parte entera de raíces cuadradas:

>>> import math
>>> math.isqrt(9)
3

>>> math.sqrt(9)
3.0

>>> math.isqrt(15)
3

>>> math.sqrt(15)
3.872983346207417

La raíz cuadrada de 9 es 3. Se puede ver que isqrt () devuelve un resultado entero, mientras que math.sqrt () siempre devuelve un flotador. La raíz cuadrada de 15 es casi 3,9. Tenga en cuenta que isqrt () trunca la respuesta a la siguiente número entero, en este caso 3.

Fi n aliado, que ca n n flujo de trabajo más fácilmente con n -dime n sio n al poi n ct un n d vectores i n la sta biblioteca dard n . Usted ca n fi n D dista del n ce entr n dos poi n ct con math.dist (), un n d la le n GTH de un vector con las matemáticas. hypot ():

>>> import math
>>> point_1 = (16, 25, 20)
>>> point_2 = (8, 15, 14)

>>> math.dist(point_1, point_2)
14.142135623730951

>>> math.hypot(*point_1)
35.79106033634656

>>> math.hypot(*point_2)
22.02271554554524

Esto hace que sea más fácil trabajar con puntos y vectores usando la biblioteca estándar. Sin embargo, si usted va a hacer muchos cálculos en puntos o vectores, que debe salir NumPy.

Las estadísticas módulo también tiene varias funciones nuevas:

  • statistics.fmean () calcula la media de los números de coma flotante.
  • statistics.geometric_mean () calcula la media geométrica de los números de coma flotante.
  • statistics.multimode () encuentra los valores que aparecen con más frecuencia en una secuencia.
  • statistics.quantiles () calcula los puntos de corte para dividir los datos en n intervalos continuos con igual probabilidad.

El siguiente ejemplo muestra las funciones en uso:

>>> import statistics
>>> data = [9, 3, 2, 1, 1, 2, 7, 9]
>>> statistics.fmean(data)
4.25

>>> statistics.geometric_mean(data)
3.013668912157617

>>> statistics.multimode(data)
[9, 2, 1]

>>> statistics.quantiles(data, n=4)
[1.25, 2.5, 8.5]

En Python 3.8, hay una nueva clase statistics.NormalDist que hace que sea más conveniente para trabajar con la distribución normal de Gauss.

Para ver un ejemplo del uso NormalDist, se puede tratar de comparar la velocidad de la nueva statistics.fmean () y el statistics.mean tradicional ():

>>> import random
>>> import statistics
>>> from timeit import timeit

>>> # Create 10,000 random numbers
>>> data = [random.random() for _ in range(10_000)]

>>> # Measure the time it takes to run mean() and fmean()
>>> t_mean = [timeit("statistics.mean(data)", number=100, globals=globals())
... for _ in range(30)]
>>> t_fmean = [timeit("statistics.fmean(data)", number=100, globals=globals())
... for _ in range(30)]

>>> # Create NormalDist objects based on the sampled timings
>>> n_mean = statistics.NormalDist.from_samples(t_mean)
>>> n_fmean = statistics.NormalDist.from_samples(t_fmean)

>>> # Look at sample mean and standard deviation
>>> n_mean.mean, n_mean.stdev
(0.825690647733245, 0.07788573997674526)

>>> n_fmean.mean, n_fmean.stdev
(0.010488564966666065, 0.0008572332785645231)

>>> # Calculate the lower 1 percentile of mean
>>> n_mean.quantiles(n=100)[0]
0.6445013221202459

En este ejemplo, se utiliza timeit para medir el tiempo de ejecución media () y F media (). Para obtener resultados fiables, se deja timeit ejecutar cada función 100 veces, y recoger 30 tales muestras de tiempo para cada función. Sobre la base de estas muestras, se crean dos objetos NormalDist. Tenga en cuenta que si ejecuta el código usted mismo, podría tardar hasta un minuto para recoger las diferentes muestras de tiempo.

NormalDist tiene muchos atributos y métodos convenientes. Consulte la documentación para obtener una lista completa. Inspeccionar y .mean .stdev, se ve que el viejo statistics.mean () se ejecuta en 0,826 ± 0,078 segundos, mientras que el nuevo statistics.fmean () pasa 0,0105 ± 0,0009 segundos. En otras palabras, F media () es aproximadamente 80 veces más rápido para estos datos.

Si necesita estadísticas más avanzadas en Python que ofrece la biblioteca estándar, echa un vistazo a statsmodels y scipy.stats.

advertencias sobre Dangerous Sintaxis

Python tiene un SyntaxWarning que pueden advertir sobre sintaxis dudoso que por lo general no es un SyntaxError. Python 3.8 añade algunos nuevos que pueden ayudarle durante la codificación y depuración.

La diferencia entre == es y puede ser confuso. Estos últimos controles para valores iguales, mientras que es sólo es cierto cuando los objetos son los mismos. Python 3.8 tratará de advertirle sobre los casos en que se debe utilizar en lugar de == es: de

>>> # Python 3.7
>>> version = "3.7"
>>> version is "3.7"
False

>>> # Python 3.8
>>> version = "3.8"
>>> version is "3.8"
:1: SyntaxWarning: "is" with a literal. Did you mean "=="?
False

>>> version == "3.8"
True

Es fácil pasar por alto una coma cuando estás escribiendo una larga lista, en especial cuando se formatean verticalmente. El olvido de una coma en una lista de tuplas dará un mensaje de error confuso sobre tuplas no ser exigible. Python 3.8, además, emite una advertencia de que apunta hacia el verdadero problema:

>>> [
... (1, 3)
... (2, 4)
... ]
:2: SyntaxWarning: 'tuple' object is not callable; perhaps
you missed a comma?
Traceback (most recent call last):
File "", line 2, in
TypeError: 'tuple' object is not callable

La advertencia identifica correctamente la coma que faltan como el verdadero culpable.

optimizaciones

Hay varias optimizaciones realizadas para Python 3.8. Algunos de los que hacer que el código funcione más rápido. Otros reducen el consumo de memoria. Por ejemplo, mirando hacia arriba campos en un namedtuple es significativamente más rápida en Python 3.8 en comparación con Python 3.7:

>>> import collections
>>> from timeit import timeit
>>> Person = collections.namedtuple("Person", "name twitter")
>>> raymond = Person("Raymond", "@raymondh")

>>> # Python 3.7
>>> timeit("raymond.twitter", globals=globals())
0.05876131607996285

>>> # Python 3.8
>>> timeit("raymond.twitter", globals=globals())
0.0377705999400132

Se puede ver que mirando hacia arriba en la .twitter namedtuple es de 30-40% más rápido en Python 3.8. Listas de ahorrar algo de espacio cuando se inicializan de iterables con una longitud conocida. Esto puede ahorrar memoria:

>>> import sys

>>> # Python 3.7
>>> sys.getsizeof(list(range(20191014)))
181719232

>>> # Python 3.8
>>> sys.getsizeof(list(range(20191014)))
161528168

En este caso, los usos lista de cerca de 11% menos de memoria en Python 3.8 en comparación con Python 3.7.

Otras optimizaciones incluyen un mejor rendimiento en el subproceso, archivos más rápida de copiar con shutil, un rendimiento mejorado de forma predeterminada en la salmuera, y más rápido operator.itemgetter operaciones. Consulte la documentación oficial para obtener una lista completa de las optimizaciones.

Por lo tanto, debe actualizar a Python 3.8? inicio de

Vamos con la respuesta simple. Si desea probar cualquiera de las nuevas características que hemos visto aquí, entonces sí es necesario para poder utilizar Python 3.8. Herramientas como pyenv y Anaconda hacer que sea fácil tener varias versiones de Python instalado al lado del otro. Como alternativa, puede ejecutar el Python 3.8 contenedor oficial del estibador. No hay ningún inconveniente para probar Python 3.8 por sí mismo.

Ahora, para las cuestiones más complicadas. Debe actualizar su entorno de producción a Python 3.8? En caso de hacer depender su propio proyecto en Python 3.8 para tomar ventaja de las nuevas características?

Usted debe tener muy pocos problemas de funcionamiento Python 3.7 código en Python 3.8. Actualización del entorno para ejecutar Python 3.8, por tanto, es bastante seguro, y que sería capaz de tomar ventaja de las optimizaciones realizadas en la nueva versión. Diferentes versiones beta de Python 3.8 ya están disponibles desde hace meses, así que espero que la mayoría de los insectos ya están aplastados. Sin embargo, si usted quiere ser conservadora, es posible que aguantar hasta la primera versión de mantenimiento (Python 3.8.1) está disponible.

Una vez que haya actualizado su entorno, se puede empezar a experimentar con características que sólo están en Python 3.8, como expresiones de asignación y posicional-únicos argumentos. Sin embargo, debe ser consciente de si otras personas dependen de su código, ya que esto les obligará a mejorar su medio ambiente. bibliotecas populares es probable que la mayoría de soportar al menos Python 3.6 durante bastante tiempo más largo.

Ver migración a Python 3.8 para obtener más información sobre cómo preparar su código para Python 3.8.

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del Real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: nuevas características Cool en Python 3.8

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *