Curso
O Python ganhou o prêmio TIOBE de "Linguagem do Ano" três vezes nos últimos quatro anos. A popular linguagem de programação ainda está no topo do índice TIOBE na metade de 2022.
A Python está no topo do Índice TIOBE para junho de 2022.
Python com classificações de 12,74% significa que a palavra-chave "Python" apareceu em cerca de ~13% de todas as consultas de mecanismos de pesquisa relacionadas à programação. Em outras palavras, toda sétima ou oitava pergunta sobre programação na Internet é sobre Python.
Atualmente, o Python é frequentemente associado aos maiores avanços em ciência de dados e IA. Os profissionais apreciam sua simplicidade, seu grande conjunto de bibliotecas integradas e de terceiros para uma infinidade de tarefas e sua comunidade.
Com a versão estável final do 3.11 chegando em 3 de outubro de 2022, a comunidade Python pode esperar por várias atualizações bem-vindas, incluindo um aumento significativo de velocidade, melhor tratamento de erros e depuração, além de várias melhorias de qualidade de vida para bibliotecas padrão.
Quais são os novos recursos do Python 3.11?
O changelog do Python 3.11 consiste em uma lista quase interminável de correções de bugs, melhorias e adições, a maioria das quais você talvez nem perceba. No entanto, alguns novos recursos essenciais podem melhorar consideravelmente seu fluxo de trabalho com Python quando a versão estável chegar. Esses novos recursos estão descritos abaixo.
1. Melhoria da velocidade
A primeira mudança significativa que entusiasmará os cientistas de dados é a melhoria da velocidade - o conjunto de benchmark padrão é executado cerca de 25% mais rápido em comparação com a versão 3.10. A documentação do Python afirma que a versão 3.11 pode ser até 60% mais rápida em alguns casos. Veja como realizar o teste de benchmark para testar as melhorias de velocidade por conta própria.
Para comparar as velocidades do Python 3.10 e 3.11, você precisará de uma instalação do Docker. Depois de se certificar de que o Docker Desktop está em execução, execute esses dois comandos no terminal, o que fará o download de duas imagens para as duas versões do Python.
$ docker run -d python:3.10.4-bullseye
$ docker run -d python:3.11-rc-bullseye
As imagens baixadas devem estar visíveis em seu painel do Docker, onde você também pode iniciá-las.
Depois de iniciar os contêineres, você pode executar o docker ps para ver detalhes como o ID do contêiner, a imagem, seu status e muito mais.
Os contêineres em execução também são visíveis na guia Contêineres do seu painel, onde você também encontrará botões CLI ao lado de "Run/Stop
". Clique neles para que ambos os contêineres iniciem duas guias de terminal anexadas aos contêineres.
Em ambas as guias, instale o pacote pyperformance
via pip
. Em seguida, execute os comandos abaixo em cada terminal de contêiner.
Para Python 3.10
$ pyperformance run -r -o py310.json
Para Python 3.11
$ pyperformance run -r -o py310.jsone run -r -o py311.json
Esses comandos executarão testes de benchmark para cerca de 60 funções Python de bibliotecas padrão e produzirão metadados JSON. Opcionalmente, adicionei a tag -r
para informar ao pyperformance
que desejo que os testes sejam rigorosos, o que leva mais tempo. No meu caso, os dois contêineres estão sendo executados em uma máquina Windows com uma CPU AMD Ryzen de 12 núcleos.
Agora, temos dois arquivos JSON em dois contêineres e precisaremos colocar ambos em um único diretório para continuar o teste de velocidade. Para isso, usaremos o comando docker cp
para copiar o arquivo JSON do contêiner Python 3.11 para o 3.10.
Execute os comandos abaixo em uma guia de terminal separada, atualizando o caminho para refletir o caminho correto em seu computador:
$ docker cp crazy_snyder:/py311.json C:/Users/bex/Desktop
$ docker cp C:/Users/bex/Desktop/py311.json charming_proskuriakova:/
No meu caso, crazy_snyder
e charming_proskuriakova
são os IDs dos contêineres em execução. Agora, os dois arquivos JSON estão no contêiner do Python 3.10. Para concluir o benchmark e salvar os resultados como um CSV, execute os comandos abaixo.
$ pyperformance compare py310.json py311.json --csv comparison.csv
$ docker cp charming_proskuriakova:/comparison.csv C:/Users/bex/Desktop/articles
Por fim, vamos carregar o CSV no Pandas e analisá-lo:
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
df = pd.read_csv("data/comparison.csv")
df.rename({"Base": "py310", "Changed": "py311", "Benchmark": "function"},
axis=1,
inplace=True)
>>> df.shape
(59, 3)
>>> df.sample(5)
Função | py310 | py311 | |
40 | scimark_monte_carlo |
0.12392 | 0.08052 |
19 | mako |
0.01967 | 0.01289 |
1 | chameleon |
0.01131 | 0.00843 |
8 | float |
0.14265 | 0.09133 |
35 | regex_effbot |
0.00315 | 0.00261 |
Cada linha do dataframe registra quanto tempo levou (em milissegundos) para que ambas as versões executassem a função Python em questão. Vamos traçar um histograma de aumentos de velocidade.
df["speed_up"] = (df["py310"] / df["py311"]).round(3)
fig, ax = plt.subplots()
sns.histplot(df["speed_up"], bins=11)
ax.set(xlabel="Speedup (times)",
title="Python 3.10 vs. Python 3.11 - speedup comparison")
plt.show()
O gráfico mostra claramente que a maioria das funções no Python 3.11 foi cerca de 1,2 vezes (20%) mais rápida. Também podemos confirmar a estimativa com a média e a mediana.
>>> df["speed_up"].mean()
1.2605593220338982
>>> df["speed_up"].median()
1.207
Parece que há um caso em que o aumento de velocidade excedeu 60%.
>>> df["speed_up"].max()
1.899
Há também quatro casos em que o Python 3.10 foi mais rápido do que a nova versão.
>>> (df["speed_up"] <= 1).sum()
4
Embora os aumentos de desempenho sejam perceptíveis no papel, o impacto específico das melhorias varia de pessoa para pessoa e a versão estável e final do Python 3.11 ainda não foi lançada. O teste de benchmark usa funções Python puras, que talvez você não use muito no seu trabalho diário, mas a configuração de uma instalação do Docker para Python 3.10 e 3.11 permitirá que você tenha uma ideia dos aumentos de velocidade para seus casos de uso específicos.
2. Melhores mensagens de erro
Outro recurso interessante do Python 3.11 é a melhoria das mensagens de erro, que aponta o local exato do erro. Em vez de retornar um traceback de 100 linhas que termina em uma mensagem de erro difícil de interpretar, o Python 3.11 aponta para a expressão exata que causou o erro.
No exemplo acima, o interpretador Python aponta para o x que travou o script devido ao seu valor None. O erro teria sido ambíguo nas versões atuais do Python, pois há dois objetos com o atributo 'x'. No entanto, o tratamento de erros do 3.11 aponta claramente a expressão problemática.
Este exemplo mostra como o 3.11 identifica um erro de um dicionário profundamente aninhado e pode mostrar claramente a qual chave o erro pertence.
Você pode ver a mesma precisão em expressões aritméticas complexas.
As mensagens de erro atualizadas são definitivamente um acréscimo bem-vindo, especialmente para cientistas de dados que têm dificuldade em depurar scripts.
3. Notas de exceção
"O explícito é melhor do que o implícito."
A frase acima é a segunda linha do Zen of Python, uma lista dos 20 princípios de design do Python. Este representa a regra de que o código Python deve ser o mais expressivo possível.
Para reforçar esse padrão de design, o Python 3.11 introduz notas de exceção(PEP 678). Agora, dentro de suas cláusulas except, você pode chamar a função add_note()
e passar uma mensagem personalizada quando ocorrer um erro.
import math
try:
math.sqrt(-1)
except ValueError as e:
e.add_note("Negative value passed! Please try again.")
raise
Se você tiver escrito uma classe de exceção personalizada como a abaixo, poderá adicionar várias notas à classe dentro do atributo protegido em nível de classe __notes__
:
import math
class MyOwnError(Exception):
# Should be a list of strings
__notes__ = ["This is a custom error!"]
try:
math.sqrt(-1)
except:
raise MyOwnError
Agora, quando o interpretador encontrar o erro, ele exibirá a mensagem personalizada após o corpo da mensagem normal.
Há também uma nova sintaxe para gerar exceções com a cláusula except*, que é usada junto com a nova classe ExceptionGroup. A PEP 654 diz que você pode usá-la para gerar vários erros não relacionados simultaneamente em vários cenários. A maioria dessas situações é muito específica, como trabalhar com soquetes da Web, programar simultaneamente com asyncio
, etc., que raramente aparecem no trabalho diário de ciência de dados, mas se você estiver interessado, poderá aprender sobre a nova sintaxe aqui.
4. Novo recurso de digitação: Autônomo
As linguagens com tipagem estática ajudam a tornar seu código legível e fácil de depurar. Definir o tipo exato de variáveis, entradas e saídas de funções pode economizar horas de depuração e facilitar a leitura do seu código para outras pessoas. A adição de anotações de digitação também permitirá que os IDEs modernos exibam as definições das funções à medida que você digita seus nomes, tornando suas funções mais fáceis de serem interpretadas por outras pessoas.
Até agora, o poderoso módulo de tipagem do Python tinha classes para praticamente qualquer tipo de dados, exceto para classes que retornam instâncias de si mesmas. Nas versões atuais do Python, o exemplo abaixo não é possível:
from typing import Self
class Language:
def __init__(self, name, version, release_date):
self.name = name
self.version = version
self.release_date = release_date
def change_version(self, version) -> Self:
self.version = version
return Language(self.name, self.version, self.release_date)
No entanto, o Python 3.11 introduz a classe Self, que você pode adicionar à definição de uma função se o valor de retorno for self ou uma nova instância da própria classe.
5. Aprimoramentos nas bibliotecas padrão
Há algumas outras melhorias na qualidade de vida das bibliotecas padrão. Em primeiro lugar, duas funções há muito esperadas foram adicionadas ao módulo de matemática.
>>> import math
>>> math.cbrt(9) # Find the cube-root of x
2.080083823051904
>>> math.cbrt(27)
3.0000000000000004
>>> math.exp2(5) # Raise 2 to the power of x
32.0
O fato de o Python ter levado 28 anos para adicionar a função de raiz cúbica é bastante surpreendente, mas, como diz o ditado, antes tarde do que nunca.
O módulo de frações também adicionou um novo recurso que permite criar frações a partir de cadeias de caracteres:
>>> from fractions import Fraction
>>> Fraction("22/7") # New in Python 3.11
Fraction(22, 7)
>>> Fraction(numerator=22, denominator=7)
Fraction(22, 7)
>>> Fraction("3e-4")
Fraction(3, 10000)
>>> Fraction("-73/41")
Fraction(-73, 41)
>>> Fraction(3.1415) # Find the closest approximation to the given float
Fraction(7074029114692207, 2251799813685248)
Como você pode ver, o módulo de frações pode ser útil para determinadas operações aritméticas. Principalmente, gosto de como você pode encontrar a fração mais próxima que se aproxima do float fornecido. Você pode dar um passo adiante, fornecendo um limite de denominador:
>>> from math import pi
>>> Fraction(pi).limit_denominator(100000)
Fraction(312689, 99532)
Há também um novo módulo chamado tomllib
para analisar documentos TOML. O TOML (Tom's Obvious Minimal Language) é um formato de arquivo popular para gravar arquivos de configuração legíveis por humanos. Aqui está uma imagem da página inicial do projeto:
import tomllib
toml_str = """
python-version = "3.11.0"
release_date = "2022-10-22"
"""
data = tomllib.loads(toml_str)
print(data) # {'python-version': '3.11.0', 'release_date': '2022-10-22'}
print(data['python-version']) # 3.11.0
print(data['release_date']) # 2022-10-22
Data de lançamento do Python 3.11
O desenvolvimento do Python 3.11 começou em 5 de maio de 2021. Desde então, sete versões alfa foram lançadas, coincidindo com a primeira versão beta em 8 de maio de 2022. A partir dessa data até o lançamento oficial, não haverá novos recursos introduzidos no Python.
A versão final e estável será lançada em 3 de outubro de 2022, depois de mais três versões beta e duas versões candidatas nesse meio tempo. Você pode saber mais sobre Python conferindo os seguintes recursos.