Versão estável do Python 3.9.0

A versão estável do Python 3.9.0 deve ser lançada hoje , 05/10/2020. A nova versão receberá atualizações de patch aproximadamente a cada 2 meses por aproximadamente 18 meses. Algum tempo após o lançamento da versão final 3.10.0, a nona e última atualização será lançada com correções de bug 3.9.



“Esta é a primeira versão do Python a usar como padrão o instalador de 64 bits no Windows. O instalador agora também proíbe ativamente a instalação no Windows 7. "

“Esta é a primeira versão do Python a usar o instalador de 64 bits no Windows por padrão. O instalador agora também impede a instalação no Windows 7. "



Eu li as notas de versão do Python 3.9 e discussões relacionadas. Com base nas informações, quis escrever um guia completo para que todos pudessem ter uma ideia das funções junto com seu trabalho detalhado.



UPD :

transição para ciclos de lançamento anuais estáveis, consulte PEP 602

alec_kalinin

“Cada nova versão do Python agora será lançada em outubro. Python 3.10 será lançado em outubro de 2021, Python 3.11 em outubro de 2022. Buckfix será lançado a cada dois meses. Esta é uma ótima notícia para mim, agora podemos claramente planejar a atualização do ambiente Python. "



PEP 584



Este PEP sugere adicionar os operadores de mesclagem ( | ) e atualização ( | = ) à classe dict integrada.



Para fundir: |



>>> a = {'milk': 'prostokvashino', 'heese': 'cheddar'} 
>>> b = {'milk': 1, 'heese': 2, 'bread': 3} 
>> >  | b 
{'milk': 1, 'heese': 2, 'bread': 3}
>>> b | a 
{'milk': 'prostokvashino', 'heese': 'cheddar', 'bread': 3}


Para atualizar: | =



>>> a | = b 
>>> a 
{'milk': 1, 'heese': 2, 'bread': 3}


A regra principal a ser lembrada é que, se houver algum conflito de chave, o valor mais à direita será preservado.



Claro, muitos pythonists terão uma pergunta, por que isso é necessário, se já existe uma opção familiar a todos



{**d1, **d2}


Esta questão foi respondida no próprio PEP:



Descompactar dicionários parece feio e não é fácil de detectar. Poucos serão capazes de adivinhar o que isso significa quando o virem pela primeira vez.


Como disse o Guido :

Peço desculpas pelo PEP 448 , mas mesmo que você saiba sobre ** d em um contexto mais simples, se você perguntasse a um usuário Python típico como combinar dois dict em um novo, duvido que muitas pessoas pensariam em {** d1, ** d2}. Eu sei que me esqueci quando este tópico começou!


Além disso, {** d1, ** d2} não funciona para subclasses de dict como defaultdict




PEP 585



Dicas de tipo genérico em coleções padrão.



Genérico é um tipo parametrizável, uma espécie de container. Também conhecido como tipo paramétrico ou tipo genérico.



Esta versão inclui suporte para sintaxe universal em todas as coleções padrão atualmente disponíveis no módulo Digitação. Podemos usar os tipos list ou dict como tipos genéricos em vez de usar typing.List ou typing.Dict .



Isso foi:



from typing import List

a: List[str] = list()

def read_files(files: List[str]) -> None:
    pass


Passou a ser:



a: list[str] = list()

def read_files(files: list[str]) -> None:
    pass


Lista completa de tipos
tuple

list

dict

set

frozenset

type

collections.deque

collections.defaultdict

collections.OrderedDict

collections.Counter

collections.ChainMap

collections.abc.Awaitable

collections.abc.Coroutine

collections.abc.AsyncIterable

collections.abc.AsyncIterator

collections.abc.AsyncGenerator

collections.abc.Iterable

collections.abc.Iterator

collections.abc.Generator

collections.abc.Reversible

collections.abc.Container

collections.abc.Collection

collections.abc.Callable

collections.abc.Set # typing.AbstractSet

collections.abc.MutableSet

collections.abc.Mapping

collections.abc.MutableMapping

collections.abc.Sequence

collections.abc.MutableSequence

collections.abc.ByteString

collections.abc.MappingView

collections.abc.KeysView

collections.abc.ItemsView

collections.abc.ValuesView

contextlib.AbstractContextManager # typing.ContextManager

contextlib.AbstractAsyncContextManager # typing.AsyncContextManager

re.Pattern # typing.Pattern, typing.re.Pattern

re.Match # typing.Match, typing.re.Match



PEP 615



Suporte de banco de dados de fuso horário IANA na biblioteca padrão.



Os fusos horários da IANA são geralmente chamados de tz ou informações de zona. Há um grande número de fusos horários da IANA com diferentes caminhos de pesquisa para especificar o fuso horário da IANA para um objeto de data e hora. Por exemplo, podemos passar o nome do caminho de pesquisa como Continente / Cidade para um objeto datetime para definir seu tzinfo.



dt: datetime = datetime(2000, 01, 25, 01, tzinfo=ZoneInfo("Europe/London"))


Se passarmos a chave errada, uma exceção será lançada

zoneinfo.ZoneInfoNotFoundError

PEP 616



Novas funções de string para remover prefixo e sufixo. Duas novas funções foram adicionadas



ao objeto str .



  • A primeira função remove o prefixo.
    str.removeprefix(prefix)
  • A segunda função remove o sufixo.
    str.removesuffix(suffix)


>>> 'hello_world'.removeprefix ('hello_') 
world
>>> 'hello_world'.removesuffix ('_world') 
hello


PEP 617



O Python 3.9 propõe substituir o atual analisador Python baseado em LL (1) por um novo analisador baseado em PEG de alto desempenho e estável.



O analisador CPython atual é baseado em LL (1). Posteriormente, a gramática é baseada em LL (1), o que permite que ela seja analisada com um analisador LL (1). O analisador LL (1) funciona de cima para baixo. Além disso, ele analisa os dados de entrada da esquerda para a direita. A gramática atual é uma gramática livre de contexto, portanto, o contexto dos tokens não é levado em consideração.

O Python 3.9 propõe substituí-lo por um novo analisador baseado em PEG, o que significa que ele removerá as limitações atuais da gramática LL do Python (1). Além disso, foram feitas correções no analisador atual, adicionando uma série de hacks que serão removidos. Como resultado, isso reduzirá o custo de manutenção a longo prazo.



Por exemplo, embora os analisadores e gramáticas LL (1) sejam fáceis de implementar, as restrições os impedem de expressar construções comuns de uma maneira natural para o designer e leitor da linguagem. O analisador procura apenas um token à frente para distinguir entre as possibilidades.



número 30966



Capacidade de cancelar futuros simultâneos .



Um novo parâmetro cancel_futures foi adicionado a concurrent.futures.Executor.shutdown () .



Este parâmetro contém todos os futuros pendentes que ainda não começaram. Antes da versão 3.9, o processo aguardava a conclusão deles antes de sair do executor.



Um novo parâmetro cancel_futures foi adicionado a ThreadPoolExecutor e ProcessPoolExecutor . Funciona quando o valor do parâmetro é True, então todos os futuros pendentes serão cancelados quando a função shutdown () for chamada .



Quando desligar ()for executado, o interpretador verifica se o executor foi coletado como lixo. Se ainda estiver na memória, ele obtém todos os itens pendentes e cancela os futuros.



número 30966



Uma série de melhorias foram feitas na biblioteca assíncio e de multiprocessamento nesta versão.



Por exemplo,



  1. O parâmetro reuse_address asyncio.loop.create_datagram_endpoint () não é mais suportado devido a problemas de segurança significativos.
  2. Adicionadas novas corrotinas, corrotinas shutdown_default_executor () e asyncio.to_thread () . Uma nova chamada para asyncio.to_thread () é usada para executar funções relacionadas a I / O em uma thread separada para evitar o bloqueio do loop de evento.


Quanto aos aprimoramentos da biblioteca de multiprocessamento, um novo método close () foi adicionado à classe multiprocessing.SimpleQueue . Este método fecha explicitamente a fila. Isso garante que a fila seja fechada e não fique mais tempo do que o esperado. É importante lembrar que os métodos get (), put (), empty () não podem ser chamados depois que a fila é fechada.







problema 37444



Bug corrigido com a importação de pacotes.



O principal problema com a importação de bibliotecas Python antes da versão 3.9 era o comportamento de importação inconsistente no Python quando as importações relativas passavam por seu pacote de nível superior.



builtins .__ import __ () gerou ValueError enquanto importlib .__ import __ () gerou ImportError.



Agora está corrigido . __Import __ () agora gera ImportError em vez de ValueError.



problema 40286



Geração de bytes aleatórios.



Outro recurso adicionado na versão 3.9 é random.Random.randbytes () . Ele pode ser usado para gerar bytes aleatórios.



Podemos gerar números aleatórios, mas e se precisássemos gerar bytes aleatórios? Antes da versão 3.9, os desenvolvedores precisavam ser criativos para gerar bytes aleatórios. Embora possamos usar os.getrandom () , os.urandom () ou secrets.token_bytes (), não podemos gerar padrões pseudo-aleatórios.



Por exemplo, para garantir que números aleatórios sejam gerados com o comportamento esperado e o processo se reproduza, geralmente usamos a semente com o módulo random.Random.



Como resultado, o método random.Random.randbytes () foi introduzido . Ele gera bytes aleatórios.



edição 28029



Correção da função de substituição de string.



O princípio da função de substituição é que para um determinado argumento máximo substituir uma ocorrência, ele substitui o conjunto de caracteres da string pelo novo conjunto de caracteres.



Para explicar melhor o problema, antes da versão 3.9, a função de substituição tinha um comportamento inconsistente:



Seria de se esperar para ver o blog



"" .replace ("", "blog", 1) 
>>> '' 




Seria de se esperar para ver |



"" .replace ("", "|", 1) 
>>> '' 




"" .replace ("", "prefix") 
>>> 'prefix'




problema 39648, problema 39479, problema 39288, problema 39310



Mudanças no módulo "matemática".



Retorna o mínimo múltiplo comum de argumentos inteiros:



>>> import  math 
>>> math.lcm(48,72,108) 
432




Retorna o maior divisor comum de argumentos inteiros. Na versão anterior, apenas dois argumentos eram suportados. Adicionado suporte para um número arbitrário de argumentos:



>>> import  math 
>>> math.gcd(9,12,21) 
3




Calcula o número de ponto flutuante mais próximo de " x " na direção de " y ".



>>> math.nextafter(2, -1)
1.9999999999999998




Este método retorna o valor do bit menos significativo do número de ponto flutuante x.



>>> 1 - math.ulp(1)
0.9999999999999998
>>> math.nextafter(1, -1) + math.ulp(1)
1.0




número 38870



O método unparse foi adicionado ao módulo ast.

O novo método pode ser usado para criar uma linha de código e depois executá-la.



>>> import ast
>>> parsed = ast.parse('from sys import platform; print(platform)')
>>> unparsed_str = ast.unparse(parsed)
>>> print(unparsed_str)
from sys import platform
print(platform)
>>> exec(unparsed_str)
win32




número 39507, número 39509



Adicionando novos códigos a http.HTTPStatus.



" Economize 418! "

418 IM_A_TEAPOT
103 EARLY_HINTS
425 TOO_EARLY




UPD :

PEP 614



Abrandamento das restrições gramaticais para decoradores.



Isso foi:



buttons = [QPushButton(f'Button {i}') for i in range(10)]

button_0 = buttons[0]

@button_0.clicked.connect
def spam():
    ...

button_1 = buttons[1]

@button_1.clicked.connect
def eggs():
    ...


Agora você pode remover atribuições desnecessárias e ligar diretamente:



buttons = [QPushButton(f'Button {i}') for i in range(10)]

@buttons[0].clicked.connect
def spam():
    ...

@buttons[1].clicked.connect
def eggs():
    ...




“A tupla deve ser colocada entre parênteses.”



Isso é baseado na visão de Guido na mesma carta. Citar:



Mas não permitirei vírgulas. Eu não posso concordar com isso



@f, g
def pooh(): ...


Isso pode levar programadores inexperientes à conclusão de que vários decoradores podem ser chamados em uma linha dessa maneira. Os parênteses são necessários para esclarecer tudo sem restrições adicionais ou sintaxe complexa.




problema17005



O novo módulo graphlib fornece funcionalidade para classificação topológica de um gráfico de nós em hash.

Mais detalhes podem ser encontrados na documentação .



UPD :Ifinik

imagem



>>> from graphlib import TopologicalSorter 
>>> graph = {'E': {'C', 'F'}, 'D': {'B', 'C'}, 'B': {'A'}, 'A': {'F'}} 
>>> ts = TopologicalSorter(graph) 
>>> tuple(ts.static_order()) 
('C', 'F', 'E', 'A', 'B', 'D')
>>> tuple(ts.static_order())
('F', 'C', 'A', 'E', 'B', 'D')


O gráfico não pode ser transferido imediatamente, mas preencha o TopologicalSorter usando o método add . Além disso, a aula é adaptada para computação paralela e pode ser usada, por exemplo, para criar uma fila de tarefas.



número 37630, número 40479



Atualizando hashlib.

Hashlib agora pode usar hashes SHA3 e SHAKE XOF do OpenSSL.

Módulos hash integrados agora podem ser desabilitados ou habilitados seletivamente, por exemplo, para forçar uma implementação baseada em OpenSSL.



Otimização



Um resumo das melhorias de desempenho do Python 3.4 para o Python 3.9:



Python version                       3.4     3.5     3.6     3.7     3.8    3.9
--------------                       ---     ---     ---     ---     ---    ---

Variable and attribute read access:
    read_local                       7.1     7.1     5.4     5.1     3.9    4.0
    read_nonlocal                    7.1     8.1     5.8     5.4     4.4    4.8
    read_global                     15.5    19.0    14.3    13.6     7.6    7.7
    read_builtin                    21.1    21.6    18.5    19.0     7.5    7.7
    read_classvar_from_class        25.6    26.5    20.7    19.5    18.4   18.6
    read_classvar_from_instance     22.8    23.5    18.8    17.1    16.4   20.1
    read_instancevar                32.4    33.1    28.0    26.3    25.4   27.7
    read_instancevar_slots          27.8    31.3    20.8    20.8    20.2   24.5
    read_namedtuple                 73.8    57.5    45.0    46.8    18.4   23.2
    read_boundmethod                37.6    37.9    29.6    26.9    27.7   45.9

Variable and attribute write access:
    write_local                      8.7     9.3     5.5     5.3     4.3    4.2
    write_nonlocal                  10.5    11.1     5.6     5.5     4.7    4.9
    write_global                    19.7    21.2    18.0    18.0    15.8   17.2
    write_classvar                  92.9    96.0   104.6   102.1    39.2   43.2
    write_instancevar               44.6    45.8    40.0    38.9    35.5   40.7
    write_instancevar_slots         35.6    36.1    27.3    26.6    25.7   27.7

Data structure read access:
    read_list                       24.2    24.5    20.8    20.8    19.0   21.1
    read_deque                      24.7    25.5    20.2    20.6    19.8   21.6
    read_dict                       24.3    25.7    22.3    23.0    21.0   22.5
    read_strdict                    22.6    24.3    19.5    21.2    18.9   21.6

Data structure write access:
    write_list                      27.1    28.5    22.5    21.6    20.0   21.6
    write_deque                     28.7    30.1    22.7    21.8    23.5   23.2
    write_dict                      31.4    33.3    29.3    29.2    24.7   27.8
    write_strdict                   28.4    29.9    27.5    25.2    23.1   29.8

Stack (or queue) operations:
    list_append_pop                 93.4   112.7    75.4    74.2    50.8   53.9
    deque_append_pop                43.5    57.0    49.4    49.2    42.5   45.5
    deque_append_popleft            43.7    57.3    49.7    49.7    42.8   45.5

Timing loop:
    loop_overhead                    0.5     0.6     0.4     0.3     0.3    0.3


O script de teste exibe o tempo em nanossegundos. Os testes foram realizados em um processador Intel Core i7-4960HQ . O código de teste pode ser encontrado no repositório em " Tools / scripts / var_access_benchmark.py " .



Obrigado pela atenção.



Link para o manual oficial do Python 3.9.

Cancele a inscrição nos comentários se você perdeu algo.



All Articles