Você está na página 1de 74

20 Python Bibliotecas voc

no est usando (mas deveria)

Caleb Hattingh

Beijing
Pequim Boston Farnham
Boston Sebastopol
Farnham Sebastopol Tquio
20 Python Bibliotecas voc no est usando (mas deveria)
por Caleb Hattingh

Copyright 2016 O'Reilly Media Inc. Todos os direitos reservados. Impresso nos

Estados Unidos da Amrica.

Publicado pela O'Reilly Media, Inc., 1005 Gravenstein estrada do Norte, Sebastopol, CA
95472.

livros da O'Reilly podem ser adquiridos para fins pedaggicos, negcios ou uso promocional de vendas. edies on-line tambm

esto disponveis para a maioria dos ttulos ( http://safaribooksonline.com ). Para mais

em formao, entre em contato com o nosso corporate / institucional Departamento de vendas:

800-998-9938 ou corporate@oreilly.com.

Editor: Dawn Schanafelt Designer de interiores: David Futato

Editor de produo: Colleen Lobner Cover Designer: Randy Comer


Editor de cpia: Christina Edwards ilustrador: Rebecca Demarest

Agosto 2016: Primeira edio

Histrico de reviso para a primeira edio

2016/08/08: First Release

O logotipo O'Reilly uma marca registrada da O'Reilly Media, Inc. 20 Python Libra- Ries voc no est usando (mas
deveria), a imagem da capa, e vestido de comrcio relacionado so marcas registradas dos O'Reilly Media, Inc.

Enquanto a editora eo autor usaram esforos de boa f para assegurar que as informaes e instrues
contidas neste trabalho so precisos, a editora eo autor assumem toda a responsabilidade por erros ou
omisses, incluindo, sem responsabilidade tao limi- por danos resultantes da utilizao ou confiana neste
trabalho. Uso das informaes e instrues contidas neste trabalho a seu prprio risco. Se todas as
amostras de cdigo ou outra tecnologia Este trabalho contm ou descreve est sujeito a abrir licenas de
cdigo ou os direitos de propriedade intelectual de outros, a sua responsabili- dade para garantir que o uso
dos mesmos em conformidade com tais licenas e / ou direitos.

978-1-491-96792-8 [LSI]
ndice

1. Expandir o seu conhecimento Python: Bibliotecas menos conhecidos. . . . . . . 1


A Biblioteca Padro 2
Na natureza 15
Mais fcil Python Embalagem com Flit 16
Aplicaes de linha de comando 19
Interfaces Grficas 26
Ferramentas do sistema 34
APIs Web com abrao 41
Datas e Horrios 46
Bibliotecas de uso geral 53
Concluso 66

v
CAPTULO 1

Expandir o seu
conhecimento Python:
Bibliotecas menos conhecidos

O ecossistema Python vasta e de longo alcance, tanto alcance e profundidade. Comeando


neste, floresta de cdigo aberto louco difcil, e mesmo com anos de experincia, ele ainda
exige esforo contnuo para manter-se atualizado com as melhores bibliotecas e tcnicas.
Neste relatrio, vamos dar uma olhada em algumas das bibliotecas Python menos
conhecidos e ferramentas. o prprio Python j inclui um grande nmero de bibliotecas de alta
qualidade; coletivamente estes so chamados a biblioteca padro. A biblioteca padro recebe
muita ateno, mas ainda existem algumas bibliotecas dentro dele que devem ser melhor
conhecidas. Vamos comear por discutir vrias ferramentas, extremamente teis na
biblioteca padro que voc pode no conhecer.

Ns tambm vamos discutir vrios emocionantes, bibliotecas menos conhecidos do


ecossistema de terceiros. Muitos de alta qualidade bibliotecas de terceiros so j bem
conhecidos, incluindo Numpy e Scipy, Django, Flask, e pedidos; voc pode facilmente
aprender mais sobre essas bibliotecas por busca de informaes online. Ao invs de focar
sobre os destaques, este relatrio , em vez vai se concentrar em vrias bibliotecas
interessantes que esto crescendo em popularidade. Vamos comear dando uma olhada
na biblioteca padro.

1
A Biblioteca Padro
As bibliotecas que tendem a receber toda a ateno so os mais fortemente usada para a
interao do sistema operacional, como sys , OS , shutil , e a uma ligeiramente menor grau, glob . Isso
compreensvel, porque a maioria das aplicaes Python lidar com o processamento de
entrada; No entanto, a biblioteca padro do Python muito rica e inclui um conjunto de
funcionalidades adicionais que muitos programadores Python levar muito tempo para dis-
tampa. Neste captulo, vou mencionar algumas bibliotecas que todo programador Python
deve saber muito bem.

colees
Primeiro temos a colees mdulo. Se voc estiver trabalhando com Python por qualquer perodo
de tempo, muito provvel que voc tenha feito uso do este mdulo; No entanto, as baterias
contidas dentro so to importantes que ns vamos passar por cima deles de qualquer maneira, apenas
no caso de.

collections.OrderedDict

collections.OrderedDict d-lhe uma dict que ir preservar a ordem na qual os itens so adicionados
a ele; note que este no o mesmo que uma ordem de classificao. 1

A necessidade de uma pedido dict trata-se, surpreendentemente, muitas vezes. Um exemplo mon
com- est processando linhas em um arquivo onde as linhas (ou alguns- coisa dentro deles) mapeia
para outros dados. Um mapeamento a soluo certa, e muitas vezes voc precisa para produzir
resultados na mesma ordem em que apareceram os dados de entrada. Aqui est um exemplo
simples de como a ordenao muda com um normal, dict:

> > > dict ( fecho eclair ( ascii_lowercase , alcance ( 4 )))


{ 'uma' : 0 , 'B' : 1 , 'C' : 2 , 'D' : 3 }

> > > dict ( fecho eclair ( ascii_lowercase , alcance ( 5 )))


{ 'uma' : 0 , 'B' : 1 , 'C' : 2 , 'D' : 3 , 'E' : 4 }

> > > dict ( fecho eclair ( ascii_lowercase , alcance ( 6 )))


{ 'uma' : 0 , 'B' : 1 , 'C' : 2 , 'D' : 3 , 'F' : 5 , 'E' : 4 }

1 Procura classificadas tipos de contineres? a excelente recipientes ordenadas pacote tem alto desempenho verses

do ordenado lista, dict, e conjunto tipos de dados.

2 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


> > > dict ( fecho eclair ( ascii_lowercase , alcance ( 7 )))
{ 'uma' : 0 , 'B' : 1 , 'C' : 2 , 'D' : 3 , 'G' : 6 , 'F' : 5 , 'E' : 4 }

Veja como a tecla " f" agora aparece antes do " e" -chave na seqncia de
teclas? Eles no aparecem na ordem dos o inser-, devido forma como o dict internos
gerenciar a atribuio de entradas de hash. o OrderedDict, no entanto, retm a
ordem na qual so inseridos itens:

> > > a partir de colees importar OrderedDict

> > > OrderedDict ( fecho eclair ( ascii_lowercase , alcance ( 5 )))


OrderedDict ([( 'uma' , 0 ), ( 'B' , 1 ), ( 'C' , 2 ), ( 'D' , 3 ), ( 'E' , 4 )])

> > > OrderedDict ( fecho eclair ( ascii_lowercase , alcance ( 6 )))


OrderedDict ([( 'uma' , 0 ), ( 'B' , 1 ), ( 'C' , 2 ), ( 'D' , 3 ), ( 'E' , 4 ), ( 'F' , 5 )])

> > > OrderedDict ( fecho eclair ( ascii_lowercase , alcance ( 7 )))


OrderedDict ([( 'uma' , 0 ), ( 'B' , 1 ), ( 'C' , 2 ), ( 'D' , 3 ), ( 'E' , 4 ), ( 'F' , 5 ), ( 'G' , 6 )])

OrderedDict: Cuidado criao com argumentos nomeados

Existe um prendedor com lamentvel OrderedDict voc precisa estar


ciente de: ele no funciona quando voc crio
a OrderedDict com argumentos de palavra-chave, uma linguagem Python muito
comum:

> > > colees . OrderedDict ( uma = 1 , b = 2 , c = 3 )


OrderedDict ([( 'B' , 2 ), ( 'uma' , 1 ), ( 'C' , 3 )])

Este parece ser um bug, mas como explicado na documen- tao, isso
acontece porque a palavra-chave argumentos so primeiro processados
como um normal dict antes de serem repassados para o OrderedDict.

collections.defaultdict

collections.defaultdict outro dicionrio caso especial: ele permite que voc especificar um valor

padro para todas as novas chaves.

A Biblioteca Padro | 3
Aqui est um exemplo comum:

> > > d = colees . defaultdict ( Lista )


> > > d [ 'uma' ] []

Voc no criou este item ainda? Sem problemas! pesquisas de chave automatica-
mente criar valores utilizando a funo fornecida quando o creat- ing defaultdict instncia.
Ao definir o valor padro como a Lista construtor no exemplo ing preced-, voc pode
evitar cdigo prolixo que se parece com isso:

d = {}
para k dentro data chave :

E se no k dentro d :

d [ k ] = []
d [ k ] . acrescentar ( ... )

o conjunto padro() Mtodo de um dict pode ser usado de uma forma um pouco semelhante ao
inicializar itens com padres, mas defaultdict resultados geralmen- te em cdigo mais claro. 2

Nos exemplos anteriores, ns estamos dizendo que cada novo elemento, por padro, ser
uma lista vazia. Se, em vez disso, voc queria cada novo ment ele- para conter um
dicionrio, voc pode dizer defaultdict (Dict).

collections.namedtuple

A prxima ferramenta, collections.namedtuple, magia em uma garrafa! Em vez de trabalhar


com este:

pilo = ( 1 , Verdade , "vermelho" )

Voc comea a trabalhar com este:

> > > a partir de colees importar namedtuple


> > > UMA = namedtuple ( 'UMA' , 'Contar cor habilitado' )
> > > pilo = UMA ( contagem = 1 , ativado = Verdade , cor = "vermelho" )
> > > pilo . contagem
1
> > > pilo . ativado
Verdade

2 Por exemplo, neste exemplo com conjunto padro() parece d.setdefault (k, []). append (...). O valor padro sempre
avaliada, enquanto que com defaultdict o gerador de valor padro avaliada somente quando necessrio.
Mas ainda h casos em que voc precisa conjunto padro(), como ao usar valores padro diferentes,
dependendo da chave.

4 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


> > > pilo . cor
"vermelho"

> > > tup A ( contagem = 1 , ativado = Verdade , cor = 'vermelho' )

A melhor coisa sobre namedtuple que voc pode adicion-lo ao cdigo existente e us-lo para
substituir progressivamente tuplas: ele pode aparecer qualquer- onde uma tupla est sendo
usado atualmente, sem quebrar o cdigo existente, e sem utilizar quaisquer recursos extras
alm do que tuplas simples exigem. utilizao namedtuple no incorre em custos de tempo de
execuo extra, e pode tornar o cdigo mais fcil de ler. A situao mais comum, onde um namedtuple
recomendado quando uma funo retorna vrios resultados, que so desempacotados em
uma tupla. Vejamos um exemplo de cdigo que usa tuplas simples, para ver por que esse
cdigo pode ser problemtico:

> > > def f ():


... Retorna 2 , Falso , "azul"
> > > contagem , ativado , cor = f ()

> > > pilo = f ()


> > > ativado = pilo [ 1 ]

funo simples retornando uma tupla.

Quando a funo avaliada, os resultados so descompactados em nomes separados.

Pior, o chamador pode acessar os valores dentro da tupla voltou


pelo ndice.

O problema com esta abordagem que este cdigo frgil a mudanas futuras. Se a
funo de alteraes (talvez alterando a ordem dos itens devolvidos, ou adicionar
mais itens), a descompactao do valor retornado ser incorreto. Em vez disso, voc
pode modificar existir
cdigo para retornar a namedtuple instncia:

> > > def f ():


... # Retornar um namedtuple!
... Retorna UMA ( 2 , Falso , "azul" )

> > > contagem , ativado , cor = f ()

Mesmo que a nossa funo agora retorna um namedtuple, o mesmo cdigo de chamada
stills obras.

A Biblioteca Padro | 5
Agora voc tambm tem a opo de trabalhar com o retornou
namedtuple no cdigo de chamada:

> > > pilo = f ()


> > > impresso ( pilo . contagem )
2

Ser capaz de usar atributos para acessar os dados dentro da tupla muito mais seguro
em vez de depender s de indexao; se futuras alteraes no cdigo adicionados
novos campos para o namedtuple, a
tup.count iria continuar a trabalhar. o colees mdulo tem alguns outros truques na manga, e

seu tempo bem gasto escovando-se sobre a documentao . Em adi- o para as classes

mostradas aqui, h tambm um Contador classe para ocorrncias facilmente de contagem, um lista-like

recipiente para eficientemente acrescentar e remoo de itens de cada extremidade ( fila de dupla

extremidade), e vrias classes auxiliares para fazer listas de subclassificao, dicts e cordas mais

fcil.

contextlib

Um gerente de contexto o que voc usa com o com declarao. Um estilo muito comum em
Python para trabalhar com dados de arquivo demonstra o gerente de contexto:

com aberto ( 'Data.txt' , 'R' ) Como f :


dados = f . ler ()

Esta uma boa sintaxe porque simplifica o Limpar passo, onde o identificador de arquivo

fechado. Utilizando o gerenciador de contexto, significa que voc no tem que se

lembrar de fazer f.close () -se: isso vai acontecer automaticamente quando o com sadas de

bloco. Voc pode usar o contextmanager decorador do contextlib

biblioteca para beneficiar deste recurso de linguagem em seus prprios esquemas nefastos. Aqui

est uma demonstrao criativo onde criamos um novo gerenciador de contexto para imprimir os

dados de desempenho (tempo). Isto pode ser til para testar rapidamente o custo do tempo de

cdigo snip- animais de estimao, como mostrado no exemplo a seguir. As notas numeradas no

so intencionalmente em ordem numrica no cdigo. Siga as notas em ordem numrica, como

mostrado a seguir o trecho de cdigo.

a partir de Tempo importar perf_counter

a partir de ordem importar ordem

a partir de contextlib importar contextmanager

6 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


@contextmanager
def cronometragem ( rtulo : str ):
t0 = perf_counter ()
rendimento lambda : ( rtulo , t1 - t0 )
t1 = perf_counter ()

com cronometragem ( '' testes de matriz ) Como total :


com cronometragem ( 'Criao innermul matriz' ) Como interior :
X = ordem ( 'D' , [ 0 ] * 1000000 )

com cronometragem ( 'Criao outermul matriz' ) Como exterior :


X = ordem ( 'D' , [ 0 ]) * 1000000

impresso ( ' total [ % s ]: % .6f s' % total ())


impresso ( ' Cronometragem [ % s ]: % .6f s' % interior ())
impresso ( ' Cronometragem [ % s ]: % .6f s' % exterior ())

o ordem mdulo na biblioteca padro tem uma abordagem incomum para inicializao: voc
passar uma seqncia existente, como uma lista grande, e ele converte os dados para o tipo
de dados de sua matriz, se possvel; no entanto, voc posso tambm criar uma matriz de uma
sequncia curta, aps o qual voc expandi-lo para o seu tamanho mximo. Alguma vez voc
j se perguntou qual mais rpido? Em um momento, vamos criar um

cronometragem gerente de contexto para medir isso e saber com certeza! A etapa chave

que voc precisa fazer para tornar seu prprio gerente de contexto usar o @ contextmanager

decorador. A seo antes do produo onde voc pode escrever cdigo que deve

executar antes do corpo de seu gerenciador de contexto ser executado. Aqui ns registrar

o timestamp antes o corpo ser executado. o produo onde a execuo transferido para

o corpo de seu gerente de contexto; no nosso caso, este o lugar onde nossas matrizes

obter cri- ado. Voc tambm pode retornar dados: aqui eu voltar um fecho que ir calcular

o tempo decorrido quando chamado. um pouco esperto mas espero que no

excessivamente: o tempo final t1 capturado dentro do fechamento, mesmo que s ser

determinada na prxima linha. Depois de produo, podemos escrever o cdigo que ser

executado quando o gerente contexto termina. Para cenrios como manipulao de

arquivos, isso seria onde voc fech-las. Neste exemplo, este o lugar onde ns

gravamos o tempo final t1.

A Biblioteca Padro | 7
Aqui ns tentamos a estratgia alternativa de criao de matriz: primeiro, criar a matriz e, em

seguida, aumentar o tamanho.

Para se divertir, usaremos nosso, novo gerente de contexto incrvel para tambm medir o
tempo total.

No meu computador, este cdigo produz esta sada:

Total de Testes [arranjo]: 0.064896 s


O tempo [de criao de matriz innermul]: 0.064195 s cronometragem
[de criao de matriz outermul]: 0.000659 s

De forma bastante surpreendente, o segundo Mtodo de produo de uma grande gama cerca de 100

vezes mais rpido do que o primeiro. Isso significa que ele Muito de

mais eficiente para criar uma pequena matriz, e depois expandi-lo, em vez de criar uma matriz

inteiramente a partir de uma lista grande.

O ponto de este exemplo no mostrar a melhor maneira de criar uma matriz: ao contrrio,
que o contextmanager decorador torna extremamente fcil de criar seu prprio gerente de
contexto, e os gerentes de contexto so uma tima maneira de fornecer um meio limpas e
seguras de gerenciamento de antes e depois de codificao tarefas.

concurrent.futures

o concurrent.futures mdulo que foi introduzido no Python 3 fornece uma maneira


conveniente de gerenciar pools de trabalhadores. Se voc j usou o mdulo
enfiar na biblioteca padro Python, voc ter visto um cdigo como este antes:

importar enfiando

def trabalhos ():


Retorna soma ( X para X dentro alcance ( 1000000 ))

fio = enfiando . Fio ( alvo = trabalhos )


fio . comear ()
fio . Junte-se ()

Este cdigo muito limpo, com apenas um segmento, mas com muitos segmentos pode
tornar-se bastante complicado para lidar com o compartilhamento de trabalho entre eles. Alm
disso, neste exemplo, o resultado da soma No obtido a partir da funo de trabalho,
simplesmente para evitar todo o cdigo extra que seria necessrio para faz-lo. Existem vrias
tcnicas para a obteno do resultado de uma funo de trabalho, tais como a passagem de
uma fila para a funo, ou subclasses threading.Thread, mas no vamos discuti-los

8 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


ainda mais, porque o multiprocessamento pacote fornece um mtodo melhor para usar
piscinas, e o concurrent.futures mdulo vai ainda mais longe para simplificar a interface. E,
semelhante a multiprocess- ing, ambas as piscinas base de fios e piscinas baseadas em
processos tm a mesma interface, tornando mais fcil para alternar entre ambos abordagens
baseadas em processo baseado em fio ou.

Aqui temos um exemplo trivial usando o ThreadPoolExecutor. Eu carrego a pgina de destino


de uma infinidade de sites populares de mdia social, e, para manter o exemplo simples,
imprimir o tamanho de cada um. Note-se que nos resultados, que mostram apenas os quatro
primeiros para manter a sada curto.

a partir de concurrent.futures importar ThreadPoolExecutor Como Executor

urls = "" "Google twitter facebook youtube pinterest Tumblr instagram reddit flickr colegas
meetup microsoft apple linkedin xing RenRen Disqus Snapchat twoo whatsapp" "" . Dividido ()

def buscar ( url ):


a partir de urllib importar pedido , erro
experimentar :

dados = pedido . urlopen ( url ) . ler ()


Retorna '{}: comprimento {}' . formato ( url , len ( dados ))
exceto erro . Erro HTTP Como e :
Retorna '{}: {}' . formato ( url , e )

com Executor ( max_workers = 4 ) Como exe :


modelo = 'Http: // www {} .com.'
empregos = [ exe . enviar (
buscar , modelo . formato ( voc )) para voc dentro urls ]
resultados = [ trabalho . resultado () para trabalho dentro empregos ]

impresso ( '\ N' . Junte-se ( resultados ))

Nossa funo de trabalho, buscar(), simplesmente transfere o URL dado. Sim, bastante

estranho hoje em dia para ver urllib porque a biblioteca de terceiros tic fantas- solicitaes de

uma tima escolha para todas as suas necessidades de acesso na Web. Contudo, urllib ainda

existe e dependendo de suas necessidades, pode permitir-lhe evitar uma dependncia

externa. Criamos um ThreadPoolExecutor exemplo, e aqui voc pode especificar quantos

trabalhadores so necessrios.

A Biblioteca Padro | 9
Empregos so criados, um para cada URL em nossa lista considervel. o
executor gerencia a entrega de postos de trabalho para os quatro threads. Esta uma

maneira simples de espera para todos os fios para retornar. Isso produz a seguinte sada (Eu

encurtou o nmero de resultados para brevidade):

http://www.google.com: comprimento 10560


http://www.twitter.com: comprimento 268924
http://www.facebook.com: comprimento 56667
http://www.youtube.com: comprimento 437754 [recorte ]

Mesmo que um trabalho criado para cada URL, limitamos o nmero de threads ativas para
apenas quatro usando max_workers e os resultados so todos capturados na lista de resultados
assim que estiverem disponveis. Se voc quisesse usar processos em vez de tpicos, tudo o
que precisa mudar a primeira linha, a partir deste:

a partir de concurrent.futures importar ThreadPoolExecutor Como Executor

Para isso:

a partir de concurrent.futures importar ProcessPoolExecutor Como Executor

Claro que, para este tipo de aplicao, que limitado pela latncia da rede, uma piscina
baseada em threads bom. com tarefas vinculadas CPU que tpicos Python so
problemticos por causa de como a segurana do thread tem sido implementado dentro do
CPython 3 intrprete de tempo de execuo, e nestas situaes o melhor usar um pool
baseada em processos vez. O principal problema com o uso de processos para paralelismo
que cada processo se limita ao seu prprio espao de memria, o que torna difcil para os
vrios trabalhadores para mastigar o mesmo pedao grande de dados. Existem maneiras de
contornar isso, mas em tais situaes tpicos fornecem um modelo de programao muito
mais simples. No entanto, como veremos no Cython na pgina 59 , H um pacote de
terceiros chamado Cython que o torna muito fcil de contornar este problema com threads.

3 CPython significa a implementao especfica da linguagem Python que est escrito na linguagem C. Existem

outras implementaes de Python, criados com vrias outras linguagens e tecnologias como .NET, Java e at
mesmo subconjuntos de si Python.

10 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


explorao madeireira

o explorao madeireira mdulo muito conhecido na comunidade de desenvolvimento web, mas


muito menos utilizada em outros domnios, como o cientficos constituem um; isso lamentvel,
porque, mesmo para uso geral, o mdulo Ging log- muito superior ao impresso() funo. No
parece assim em primeiro lugar, porque o impresso() funo to simples; No entanto, uma vez que
voc inicializar explorao madeireira, ele pode olhar muito semelhante. Por exemplo, comparar estes
dois:

impresso ( ' Esta a sada para o console' )

logger . depurar ( 'Esta a sada para o console' )

A grande vantagem deste ltimo que, com uma nica mudana para um ting set- na instncia
logger, voc pode mostrar ou ocultar todas as suas mensagens de depurao. Isto significa que
voc no precisa mais passar pelo processo de comentar e descomentando seu impresso() afirmaes,
a fim de mostrar ou escond-los. explorao madeireira tambm lhe d um pouco diferentes nveis de
modo que voc pode ajustar a verbosidade de sada em seus programas. Aqui est um exemplo
de diferentes nveis:

logger . depurar ( 'Isto para depurao. Muito falante!' )


logger . informaes ( 'Isto para tagarelice normal' )
logger . Ateno ( 'Os avisos devem quase sempre ser visto.' )
logger . erro ( 'Voc definitivamente quer ver todos os erros!' )
logger . crtico ( 'ltima mensagem antes de um acidente de programa!' )

Outro truque realmente puro que quando voc usar o log, escrevendo sbios men- durante
o tratamento de excees muito mais fcil. Voc no tem que lidar com sys.exc_info () e a traceback
mdulo apenas para imprimir a mensagem de exceo com um rastreamento. Voc pode
fazer isso em vez disso:

experimentar :

1/0
exceto :
logger . exceo ( "Algo falhou:" )

Apenas essas quatro linhas produz um rastreamento completo na sada:

ERRO: root: Algo falhou: Traceback (chamada


mais recente passada):
File "logtb.py", linha 5, em <module>
1/0
ZeroDivisionError: diviso por zero

A Biblioteca Padro | 11
Anteriormente eu disse que a explorao madeireira requer alguma configurao. A documentao para o explorao

madeireira mdulo extensa e pode parecer esmagadora; aqui uma receita rpida para voc comear:

# Top do arquivo
importar explorao madeireira

logger = explorao madeireira . getLogger ()

# Todo o seu cdigo normal vai aqui


def blah ():
Retorna ' bl'

# Parte inferior do arquivo


E se __nome__ == '__ a Principal__' :

explorao madeireira . basicConfig ( nvel = explorao madeireira . DEPURAR )

Sem argumentos, o getLogger () devolve o raiz


logger, mas mais comum para criar uma nomeado logger. Se voc est apenas comeando,

explorando com o registrador de raiz muito bem. Voc precisa chamar um configurao mtodo;

Caso contrrio, as chamadas para o logger no registrar qualquer coisa. O passo de

configurao necessrio. No precedente basicConfig () linha, por mudando apenas log ging.DEBUG dizer,

logging.WARNING, voc pode afetar o que men- sbios so processadas e quais no.

Finalmente, h um truque que voc pode usar para facilmente alterar o nvel Ging log-na
linha de comando. scripts em Python que so cutable diretamente exe- geralmente tm o
cdigo de inicializao em um bloco condicional comeando com se __name__ == '__main__'. Este
o lugar onde
parmetros de linha de comando so tratadas, por exemplo, utilizando o argparse
biblioteca na biblioteca padro Python. Podemos criar argumentos de linha de comando
especificamente para o nvel de log:

# Parte inferior do arquivo


E se __nome__ == '__ a Principal__' :

a partir de argparse importar analisador ArgumentParser = ArgumentParser ( descrio = 'Meu


aplicativo que meu' )
parser . add_argument ( '-ll' , '--loglevel' ,
tipo = str ,
escolhas = [ 'DEPURAR' , 'INFO' , 'ATENO' , 'ERRO' , 'CRTICO' ],
Socorro = 'Definir o nvel de log' )
args = parser . parseargs ()
explorao madeireira . basicConfig ( nvel = args . loglevel )

Com esta configurao, se voc ligar o seu programa com

12 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


$ Python main.py DEBUG -ll

ele ser executado com o conjunto de nvel de registo para DEBUG ( por isso todas as mensagens logger

ser mostrado), enquanto que se voc execut-lo com

$ Python main.py AVISO -ll

ele ser executado no ATENO nvel para o registo, ento tudo INFO e DEPURAR

mensagens logger sero ocultados.

H muitos mais recursos lotaram o explorao madeireira mdulo, mas eu espero que eu tenha
convencido de que voc considere a us-lo em vez de usar
impresso() para o seu prximo programa. H muito mais informaes sobre o explorao

madeireira mdulo on-line, tanto no Python oficial docu- mentao e em outros lugares em

blogs e tutoriais. O objetivo aqui apenas para convenc-lo de que o explorao madeireira mdulo
vale ing investigat-, e comear a trabalhar com ele fcil de fazer.

sched

Existe um interesse crescente na criao de bots 4 e outras aplicaes acompa- nhamento e


automao. Para estas aplicaes, um requisito mon com- para executar aes em
horrios especficos ou intervalos especificados. Esta funcionalidade fornecida pela sched ule
mo- na biblioteca padro. J existem ferramentas similares fornecidos por sistemas
operacionais, tais como cron em Linux e Agendador de Tarefas do Windows, mas com Python
do prprio sched mdulo que voc pode ignorar essas diferenas de plataforma, bem como
incorporam tarefas agendadas em um programa que pode ter muitas outras funes. o documentao
para sched bastante concisa, mas espero que estes exemplos ir ajudar a comear. A
maneira mais fcil de comear marcar uma funo a ser executada aps um atraso
especificado (este um exemplo completo para se certificar de que voc pode execut-lo
com sucesso):

importar sched
importar Tempo

a partir de data hora importar data hora , timedelta

Agendador = sched . Agendador ( timefunc = Tempo . Tempo )

def saytime ():

4 programas que automatizam alguma tarefa, muitas vezes, a comunicao de dados entre os diferentes servios de rede como o

Twitter, IRC, e Slack.

A Biblioteca Padro | 13
impresso ( Tempo . ctime ())
Agendador . entrar ( 10 , prioridade = 0 , aao = saytime )

saytime ()
experimentar :

Agendador . corre ( bloqueando = Verdade )


exceto KeyboardInterrupt :
impresso ( ' Parado.' )

Um exemplo programador criado. A funo de trabalho declarado, no nosso caso saytime

(), que sim- impresses ply fora a hora atual.

Note que reprogramar a funo dentro de si, com um segundo de atraso de dez.

O programador iniciado com executar (bloqueando = TRUE), e o ponto cution exe-


permanece aqui at que o programa terminada ou Ctrl-C pressionada.

Existem alguns detalhes irritantes sobre a utilizao sched: voc tem que passar timefunc = time.time como
este no definida por padro, e voc tem que fornecer uma prioridade, mesmo quando no
necessrio. No entanto, globalmente, o

sched mdulo ainda fornece uma maneira limpa para obter cron- comportamento semelhante. Trabalhando

com atrasos pode ser frustrante se o que voc realmente queremos que uma tarefa para executar em

horrios especficos. Alm de entrar(), uma sched

exemplo tambm fornece o enterabs () mtodo com o qual voc pode acionar um evento em um
momento especfico. Podemos usar esse mtodo para acionar uma funo, digamos, a cada todo minuto:

importar sched
importar Tempo

a partir de data hora importar data hora , timedelta

Agendador = sched . Agendador ( timefunc = Tempo . Tempo )

def reagendar ():


NEW_TARGET = data hora . agora () . substituir (
segundo = 0 , microssegundo = 0 )
NEW_TARGET + = timedelta ( minutos = 1 )
Agendador . enterabs (
NEW_TARGET . timestamp (), prioridade = 0 , aao = saytime )

def saytime ():


impresso ( Tempo . ctime (), rubor = Verdade )

14 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


reagendar ()

reagendar ()
experimentar :

Agendador . corre ( bloqueando = Verdade )


exceto KeyboardInterrupt :
impresso ( ' Parado.' )

Crie um Agendador exemplo, como antes. Obter hora atual, mas retirar segundos e

microssegundos para obter um minuto inteiro.

O tempo alvo exatamente um minuto frente de toda a atual minuto. o enterabs

() horrios mtodo a tarefa. Este cdigo produz o seguinte resultado:

Sat junho 18 18 : 14 : 00 2016


Sat junho 18 18 : 15 : 00 2016
Sat junho 18 18 : 16 : 00 2016
Sat junho 18 18 : 17 : 00 2016
Parado .

Com o crescente interesse em Internet das coisas aplicaes, o built-in sched biblioteca
fornece uma maneira conveniente de gerenciar tarefas tivas repetitivos. o documentao fornece
mais informaes sobre como cancelar tarefas futuras.

Na natureza
De agora em diante vamos olhar para algumas bibliotecas Python de terceiros que voc
pode ainda no ter descoberto. Existem milhares de pacotes excelentes descritos no o guia
Python .

H algumas guias semelhantes a este relatrio que voc pode encontrar online. No poderia
haver tantos como bibliotecas Python favoritos listas como h desenvolvedores de Python, e
por isso a seleo aqui apresentada necessariamente subjectiva. Passei muito tempo
encontrar e testar vari- bibliotecas de terceiros ous a fim de encontrar essas jias escondidas.

Na natureza | 15
Meus critrios de seleco eram de que uma biblioteca deve ser:

fcil de usar

fcil de instalar

cruzada plataforma

aplicvel a mais de um domnio

ainda no super-popular, mas provavelmente tornar-se to

a X fator

Os dois ltimos itens dessa lista ter mais explicaes. A popularidade difcil definir
exatamente, uma vez que diferentes bibliotecas tendem a se acostumar com diferentes
graus dentro de diferentes comunidades Python. Por exemplo, numpy e Scipy so muito mais
fortemente utilizado dentro do cientfico comunidade Python, enquanto Django e frasco desfrutar
de mais ateno na comunidade de desenvolvimento web. Alm disso, a popularidade
dessas bibliotecas tal que todo mundo j sabe sobre eles. Um candidato para esta lista poderia
foram alguns- coisa como dask , Que parece prestes a se tornar uma eventual sor sucesso
para Numpy, mas a mdio prazo, provvel que seja mais aplicvel para a comunidade
cientfica, falhando assim o meu teste de aplicabilidade. o X fator significa que as coisas
realmente legais so susceptveis de ser construdo com essa biblioteca Python. Tal critrio
, naturalmente, fortemente subjetivo, mas espero que, ao fazer essas selees, para
inspir-lo a experimentar e criar algo novo!

Cada um dos captulos seguintes descreve uma biblioteca que preencheram todos os critrios
na minha lista, e que eu acho que voc vai achar til em suas atividades dirias Python, no
importa a sua especializao.

Mais fcil Python Embalagem com Flit


voar uma ferramenta que simplifica drasticamente o processo de apresentao de um pacote Python

para o Python Package Index (PyPI). o processo tradicional comea com a criao de um setup.py Arquivo;

simplesmente para descobrir como fazer isso requer uma quantidade considervel de trabalho at

mesmo para suporte de sub o que fazer. Em contraste, fogem ir criar seu arquivo de configurao

interao vamente, e para pacotes tpicos simples que voc estar pronto para fazer o upload para PyPI

quase imediatamente. Vamos dar uma olhada: considerar essa estrutura simples pacote:

16 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


$ rvore
.
mypkg
__init__.py
main.py

Do pacote nisso arquivo um timo lugar para adicionar pacote de informa- o, como
documentao, nmeros de verso, e autor informa- o.

Depois de instalar flit em seu ambiente com pip instalar flit,


voc pode executar o initializer interativo, que ir criar sua configurao sentido
apropriado. Ele pede apenas cinco perguntas, a maioria dos quais ter padres aplicveis
depois de ter feito o seu primeiro pacote com
flit:

$ Flit de inicializao Nome do


mdulo [mypkg]: Autor [Caleb
Hattingh]:
Autor de e-mail [caleb.hattingh@gmail.com]: Home page
[https://github.com/cjrh/mypkg]: Escolha uma licena

1. MIT
2. Apache
3. GPL
4. balde - escolher uma licena depois Enter 1-4
[2]: 2
flit.ini escritos; editar esse arquivo para adicionar informaes extra opcional.

A linha final diz que um flit.ini arquivo foi criado. Vamos dar uma olhada em que:

$ Cat flit.ini //
[metadados] module =
mypkg
author = Caleb Hattingh
autor-email = caleb.hattingh@gmail.com home-page =
https://github.com/cjrh/mypkg
classificadores = Licena :: Aprovada OSI :: Apache Software License

praticamente o que ns especificado na interativo flit o init


seqncia. Antes que voc possa enviar o nosso pacote para o PyPI online, existem mais duas
etapas que devem ser concludas. A primeira dar o seu pacote de uma docstring. Voc pode
adicionar isso mypkg / __ init__.py Arquivo na parte superior usando aspas triplas ( "" "). A segunda
que voc deve adicionar uma linha para a verso para o mesmo arquivo. Seu terminou __ init__.py arquivo
pode ter esta aparncia:

Mais fcil Python Embalagem com Flit | 17


# file: __init__.py
"" "Esta a documentao para o pacote. ''"

__version__ = '1.0.0'

Esta documentao ser usado como sua descrio do pacote em PyPI.

Da mesma forma, a marca de verso dentro do seu pacote tambm ser reutilizada para
PyPI quando o pacote carregado. Estes grations inte- automticas ajudam a simplificar o
processo de embalagem. Pode no parecer muito, adquirida, mas a experincia com
embalagens Python vai mostrar que muitos passos (mesmo quando eles so simples),
quando combinados, podem levar a uma experincia de embalagem complexo. 5

Depois de preencher a descrio bsica ea verso, voc est pronto para construir uma
roda e envi-lo para PyPI:

$ flit roda --upload arquivo de pacote de cpia ( s ) de


mypkg Escrevendo arquivos de metadados
Escrevendo o registro de arquivos

Roda construda: dist / mypkg-1.0.0-py2.py3-nenhuns-any.whl Usando repositrio em


https://pypi.python.org/pypi upload de dist / mypkg-1.0.0-py2.py3-nenhuns-alguma
.whl ... A partir nova conexo HTTPS ( 1 ) : Carregamento de pypi.python.org proibido;
tentando registrar e fazer o upload novamente Iniciando nova conexo HTTPS ( 1 ) :
Pypi.python.org mypkg registrado com PyPI

Upload dist / mypkg-1.0.0-py2.py3-nenhum-any.whl ... A partir nova


conexo HTTPS ( 1 ) : Pypi.python.org pacote est em
https://pypi.python.org/pypi/mypkg

Note-se que voam registra automaticamente o seu pacote se o upload inicial falhar.

E isso! Figura 1-1 mostra nosso pacote em PyPI.

5 A XYZ esquema de verso mostrada aqui conhecido como de verses semntica ( Semver), mas um esquema
alternativo vale a pena investigar ainda versionamento calendrio, que voc pode aprender mais sobre a calver.org .

18 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


Figura 1-1. Est vivo! Nosso pacote demo no PyPI.

voar permite especificar mais opes, mas para pacotes simples que voc v aqui
pode chegar muito longe.

Aplicaes de linha de comando


Se voc j passou algum momento qualquer desenvolvimento de cdigo Python, voc certamente vai

ter usado vrios aplicativos de linha de comando. Alguns programas de linha de comando parece muito

mais amigvel do que outros, e neste captulo, mostramos duas bibliotecas fantsticos que ir tornar

mais fcil para voc para oferecer a melhor experincia para os usurios de seus prprios aplicativos

de linha de comando. Colorama permite a utilizao de cores em sua sada, enquanto comea torna mais

fcil para fornecer uma interface rica para a especificao e processamento de opes de linha de

comando.

Colorama

Muitos de seus programas em Python de desktop s vai ser usado na linha de comando,
por isso faz sentido para fazer o que pode para melhorar a experincia de seus
usurios, tanto quanto possvel. O uso de cor pode melhorar drasticamente a sua
interface de usurio, e Colorama
faz com que seja muito fcil de adicionar toques de cor em seus aplicativos de linha de comando.

Vamos comear com um exemplo simples.

Aplicaes de linha de comando | 19


a partir de Colorama importar nisso , dianteiro , Costas , estilo de inicializao ( autoreset = Verdade

mensagens = [
'bl bl bl' , ( dianteiro . LIGHTYELLOW_EX + Estilo . BRILHANTE

+ COSTAS . MAGENTA + 'Alerta!!!' ),


'bl bl bl'
]

para m dentro mensagens :

impresso ( m )

Observe no Figura 1-2 como a mensagem importante salta para a direita para fora em voc? H
outros pacotes como maldies, bnos, e prompttoolkit que permitem que voc faa muito mais com
a prpria tela do terminal, mas eles tambm tm uma curva de aprendizagem ligeiramente mais
acentuada; com colo rama a API simples o suficiente para ser fcil de lembrar.

Figura 1-2. Adicionar cor s suas mensagens de sada com simples corda catenation con-.

A grande coisa sobre Colorama que ele tambm funciona no Windows, alm de Linux e
Mac OS X. No exemplo anterior, foi utilizado o nisso() funo para permitir rearme
automtico para o padro cores aps cada impresso(), mas mesmo quando no
necessrio, nisso() deve ser sempre

20 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


chamada (quando o cdigo executado no Windows, o nisso() chamada permite o mapeamento de
cdigos de cores ANSI para o sistema de cores do Windows).

a partir de Colorama importar inicializao de

inicializao ()

O exemplo anterior clara o suficiente para seguir, mas eu gostaria de ser um autor muito se
eu-depois de ter enfatizado os benefcios da explorao madeireira
module-lhe disse que a nica maneira de obter cores em seu console era usar impresso().
Como de costume com Python, verifica-se que o trabalho duro j foi feito para ns.
Depois de instalar o colorlog
pacote, 6 voc pode usar cores em suas mensagens de log imediatamente:

importar colorlog

logger = colorlog . getLogger ()


logger . setlevel ( colorlog . colorlog . explorao madeireira . DEPURAR )

treinador = colorlog . StreamHandler ()


treinador . setFormatter ( colorlog . ColoredFormatter ())
logger . addHandler ( treinador )

logger . depurar ( "Mensagem de depurao" )


logger . informaes ( "Mensagem de informao" )
logger . Ateno ( "Mensagem de aviso" )
logger . erro ( "Mensagem de erro" )
logger . crtico ( "Mensagem crtica" )

Obter um logger exemplo, exatamente como voc faria normalmente. Defina o nvel de log.

Voc tambm pode usar as constantes como DEPURAR

e INFO a partir do mdulo de log directamente. Definir o formatador de mensagem

para ser o ColoredFormatter fornecida pelo colorlog biblioteca. Isto produz a sada

mostrada na Figura 1-3 .

Existem vrios outros pacotes Python semelhante vale a pena assistir, como o fabuloso De
linha de comando beautifier, o que teria feito esta lista se ele tinha sido atualizado para
Python 3 apenas algumas semanas mais cedo!

6 pip instalar colorlog

Aplicaes de linha de comando | 21


Figura 1-3. belas cores e automticas para suas mensagens de log.

comea

Na medida em que interfaces de usurio ir, a maioria dos programas em Python comeam como
aplicativos de linha de comando, e muitos permanecem assim. Faz sentido de oferecer a seus
usurios a melhor experincia possvel. Para tais gramas pr, as opes so especificadas com
argumentos de linha de comando e da biblioteca padro Python oferece a argparse biblioteca para
ajudar com isso.

argparse uma robusta implementao slida para a linha de comando pro- cessamento,
mas pouco detalhado de usar. Por exemplo, aqui temos um roteiro extremamente simples
que ir adicionar dois nmeros passados na linha de comando:

importar argparse

def a Principal ( uma , b ):

"Script" "Curto para adicionar dois nmeros ''"


Retorna uma + b

E se __nome__ == '__ a Principal__' :

parser = argparse . ArgumentParser (


descrio = "Adicionar dois nmeros" )
parser . add_argument ( '-uma' ,
Socorro = 'Primeiro valor' ,
tipo = flutuador ,
padro = 0 )

22 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


parser . add_argument ( '-b' ,
Socorro = 'Segundo valor' ,
tipo = flutuador ,
padro = 0 )
args = parser . parse_args ()
impresso ( a Principal ( args . uma , args . b ))

Como seria de esperar, a ajuda pode ser obtido pela passagem - h para este pro- grama:

$ python argparsedemo.py uso -h: argparsedemo.py [ -h ] [ -a A ]


[ -b B ]

Adicionar dois nmeros

argumentos opcionais:
- h, --help mostrar esta Socorro mensagem e Sada
-aa primeiro valor
-bb segundo valor

Em contraste, o comea biblioteca leva um faco para a API de arg parse e maximamente
explora caractersticas da linguagem Python para simplificar a configurao da mesma
interface de linha de comando:

importar incio

@ begin.start ( auto_convert = Verdade )


def a Principal ( uma : 'Primeiro valor' = 0.0 , b : 'Segundo valor' = 0.0 ):
"" "Adicionar dois nmeros ''"
impresso ( uma + b )

H tanta coisa acontecendo em to poucas linhas, mas tudo ainda explcito:

Cada parmetro na funo principal se torna um argumento de linha de comando.

o anotaes de funo so exploradas para fornecer uma descrio em linha ajuda de


cada parmetro.

O valor padro de cada parmetro (aqui, 0.0) usado tanto como um valor padro, bem
como para indicar o tipo de dados exigida (neste caso, um flutuador valor nmero).

o auto_convert = True usada para impor tipo de coero de uma string para o tipo
de parmetro alvo.

O docstring para o funo torna-se agora a ajuda do material recolhido do prprio


programa.

Aplicaes de linha de comando | 23


Alm disso, voc pode ter notado que este exemplo no tem o costume se __name__ ==
'__main__' clich: isso porque comea inteligente o suficiente para trabalhar com

quadros de pilha do Python para que seu o fun- alvo torna-se o ponto de partida. Para
completar, aqui a ajuda para o begins- verso, produzida com - h:

$ python beginsdemo.py uso -h: beginsdemo.py [ -h ] [ --uma A ]


[ --b B ]

Adicionar dois nmeros

argumentos opcionais:
- h, --help mostrar esta Socorro mensagem e Sada
- - a A, -A um primeiro valor ( padro: 0,0 )
- - b B, -b Segundo valor B ( padro: 0,0 )

H um grupo mais truques que comea torna disponveis, e que so incentivados


a ler a documentao ; por exemplo, se os parmetros so palavras:

@ begin.start
def a Principal ( diretrio : 'Dir Target' ):
...

em seguida, ambos - d VALOR e - VALOR diretrio vai trabalhar para specify- ing o valor da diretrio
parmetro na linha de comando. Uma sequncia de argumentos posicionais de comprimento
desconhecido facilmente definida com desempacotamento:

# demo.py
@ begin.start
def a Principal ( diretrio : 'Dir Target' , * filtros ):
...

Quando chamado com:

$ python demonstrao . py - d / casa / tmp utilizador Temp Temp

a filtros argumento seria a lista [' tmp', 'temp', 'temp'].

Se isso fosse tudo o que comea suportado, ele j seria suficiente para a grande maioria
dos programas simples; Contudo, comea Tambm vides pr suporte para subcommands:

importar incio

@ begin.subcommand
def estado ( compactar : 'Formato curto ou longo' = Verdade ):
"" "Relate a situao atual. ''"

24 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


E se compactar :

impresso ( ' Est bem.' )

outro :
impresso ( ' Muito bem, obrigado.' )

@ begin.subcommand
def buscar ( url : 'Fonte de dados' = 'Http://google.com' ):
"" "Fetch dados do URL. ''"
impresso ( ' Trabalho vai aqui' )

@ begin.start ( auto_convert = Verdade )


def a Principal ( uma : 'Primeiro valor' = 0.0 , b : 'Segundo valor' = 0.0 ):
"" "Adicionar dois nmeros ''"
impresso ( uma + b )

o a Principal funo a mesma de antes, mas ns adicionamos dois comandos sub:

O primeiro, status, representa um subcomando que poderia ser usado para fornecer algum
tipo de status do sistema mensagem (acho que tus esta- git).

O segundo, buscar, representa um subcomando para algum tipo de funo de trabalho


(acho que git fetch).

Cada subcomando tem seu prprio conjunto de parmetros e as regras funcionam da


mesma maneira como antes com o a Principal funo. Por exemplo, observe a ajuda
atualizado (obtido com o - h parmetro) para o programa:

$ python beginssubdemo.py uso -h: beginssubdemo.py [ -h ] [ --uma A ] [ --b B ] { buscar, estado } ...

Adicionar dois nmeros

argumentos opcionais:
- h, help mostrar esta Socorro mensagem e Sada
- - um A, -a Um primeiro valor ( padro: 0,0 )
- - b B, B -b segundo valor ( padro: 0,0 )

subcommands disponveis:
{ buscar, estado }
buscar Buscar dados de URL.
estado Relatar o status atual.

Aplicaes de linha de comando | 25


Ns ainda temos a mesma documentao para o programa principal, mas ajuda agora
adicional para os subcomandos foram adicionados. Note-se que as docstrings de funo para estado
e buscar Tambm foram recicladas em CLI descries de ajuda. Aqui est um exemplo de
como o nosso programa poderia ser chamado:

$ python beginssubdemo.py -a 7 -b 7 --compact estado


14,0
ok.

$ python beginssubdemo.py -a 7 -b 7 estatuto --no-compacto


14.0
Muito bem, obrigado.

Voc tambm pode ver como boleano parmetros de obter algum trata- mento especial: eles avaliam Verdade

se estiver presente e Falso quando no- prefixado para o nome do parmetro, tal como mostrado para o

parmetro compactar.

comea tem ainda mais truques na manga, como dling Han- automtica para variveis
ambientais , arquivos de configurao , tratamento de erros e
explorao madeireira E eu mais uma vez exort-lo para verificar o projeto docu- mentao. E

se comea parece muito radical para voc, h um monte de outras ferramentas para facilitar a

criao de interfaces de linha de comando. Uma opo parti- cular que vem crescendo em

popularidade clique .

Interfaces Grficas
Python oferece uma riqueza de opes para a criao grfica do usurio inter enfrenta (GUIs),
incluindo PyQt , wxPython e tkinter , Que tambm est disponvel diretamente na biblioteca padro.
Neste captulo iremos descrever duas adies significativas, mas em grande parte desconhecidas,
para a formao em linha. O primeiro, pyqtgraph, muito mais do que simplesmente uma chart-
biblioteca de plotagem, enquanto pywebview d-lhe uma interface de tecnologia na Web com
recursos completos para suas aplicaes Python desktop.

pyqtgraph

A biblioteca de plotagem grfico mais popular em Python matplotlib , Mas voc pode ainda no
ter ouvido falar da alternativa maravilhosa, pyqtgraph . Pyqtgraph no uma substituio de
um-para-um para matplotlib; em vez disso, ele oferece uma seleco de caractersticas diferentes
e, em particular, excelente para em tempo real e visualizao interativa.

26 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


muito fcil obter uma idia do que pyqtgraph oferece: basta executar o aplicativo
embutido exemplos:

$ pip instalar pyqtgraph


$ python -m pyqtgraph.examples

Isto ir instalar e executar o navegador exemplos. Voc pode ver uma imagem de
um dos exemplos em Figura 1-4 .

Figura 1-4. janela pyqtgraph Interactive.

Este exemplo mostra um conjunto de grficos interactivos. Voc no pode dizer a partir da
imagem, mas quando voc executar esse exemplo, o grfico amarelo da direita uma
animao de alta velocidade. Cada parcela, incluindo o anima- ted um (em amarelo), pode
ser deslocada e escalado em tempo real com o cursor. Se voc j usou estruturas GUI
Python no passado, e em particular aqueles com de forma livre grficos, voc provavelmente
esperar um desempenho lento. Este no o caso com pyqtgraph: Porque

pyqtgraph usa, sem surpresa, PyQt para a UI. Isso permite PyQt

Interfaces Grficas | 27
grfico -se a ser um pacote puro-python, tornando a instalao e distribuio fcil. 7

Por padro, a configurao de estilo para grficos em pyqtgraph usa um fundo preto com um
primeiro plano branco. Dentro Figura 1-4 , Eu secretamente usou uma alterao de configurao
de estilo para inverter as cores, j que fundos escuros olhar terrvel na impresso. Essas
informaes tambm esto disponveis na documentao:

importar pyqtgraph Como pg

# Passar a usar fundo branco e preto primeiro plano


pg . setConfigOption ( 'fundo' , 'W' )
pg . setConfigOption ( 'primeiro plano' , 'K' )

H mais para oferecer do que grficos simplesmente plotagem: pyqtgraph tambm tem recursos
para visualizao 3D, encaixe widget, e os widgets de dados automticos com ligao
bidireccional. Dentro Figura 1-5 , De entrada de dados e widgets de manipulao foram gerados
automaticamente a partir de uma matriz de tabela Numpy, e interaco com estes elementos IU
muda automaticamente o grfico.

pyqtgraph normalmente usado como um visualizador direta, muito parecido como plotlib mat usado,

mas com uma melhor interatividade. No entanto, tambm bastante fcil Embutir pyqtgraph em outra

separada PyQt o aplicabilidade ea documentao para isso fcil de seguir. pyqtgraph tambm

fornece alguns extras teis, como editar widgets que so as unidades de reconhecimento

(quilogramas, metros e assim por diante), e widgets de rvores que podem ser construdos

automaticamente a partir de (aninhados!) estruturas de dados Python padro, como listas,

dicionrios e matrizes. O autor do pyqtgraph est agora a trabalhar com os autores de outros pacotes

de visualizao sobre um novo pacote de visualizao de alto desempenho: vispy . Com base em

quo til pyqtgraph tem sido para mim, eu no tenho nenhuma dvida de que vispy provvel que se

torne uma ferramenta indispensvel para a visualizao de dados.

7 Infelizmente, PyQt em si pode ser trivial ou muito complicado para instalar, dependendo da sua plataforma. No momento da

escrita, a verso estvel do pyqtgraph exige PyQt4 para os quais no instalador pr-construda est disponvel em PyPI; no

entanto, o ramo de desenvolvimento de

pyqtgraph funciona com PyQt5, para o qual um pr-construdos, PIP- verso instalvel faz existir em PyPI. Com alguma

sorte, pelo tempo que voc ler isto uma nova verso do pyqtgraph tero sido libertados!

28 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


Figura 1-5. Outro exemplo pyqtgraph: os campos de dados e widgets esquerda so criados
automaticamente a partir de uma matriz de tabela Numpy.

pywebview

H um grande nmero de maneiras de fazer rea de Trabalho aplicaes GUI com Python,
mas nos ltimos anos a ideia de usar uma interface de navegador-like como uma interface
cliente de desktop tornou-se popular. Esta abordagem baseada em ferramentas como cefpython
(Utilizando a estrutura integrada cromadas) e Eltron , Que tem sido usada para construir
muitas ferramentas populares, como o editor de texto Atom e aplicao de mensagens
sociais Slack.

Normalmente, essa abordagem envolve agregao de um motor de navegador com o seu


pedido, mas Pywebview d-lhe um comando de uma linha para criar uma janela de GUI que
envolve um nativo do sistema janela vista web. Ao combinar isso com uma pton abb web
como Flask ou garrafa, torna-se muito fcil criar uma aplicao local com uma interface
grfica, ao mesmo tempo, tirando partido das mais recentes tecnologias de GUI que foram
desenvolvidos no espao browser. A vantagem de usar o widget sistema de navegador nativo
que voc no tem que distribuir um pacote de aplicativos potencial- mente grande para seus
usurios.

Vamos comear com um exemplo. Desde a nossa candidatura ser construda como um modelo
de pgina da web em HTML, pode ser interessante usar uma ferramenta Python para construir o
HTML em vez de escrev-lo com a mo.

Interfaces Grficas | 29
a partir de corda importar ascii_letters
a partir de aleatria importar escolha , randint
importar webview
importar dominar
a partir de dominate.tags importar *

a partir de garrafa importar rota , corre , modelo

inicializao = 'Https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/'
bootswatch = 'Https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/'

doutor = dominar . documento ()

com doutor . cabea :

ligao ( rel = 'Estilo' ,


href = inicializao + 'Css / bootstrap.min.css' )
ligao ( rel = 'Estilo' ,
href = bootswatch + 'Papel / bootstrap.min.css' )
roteiro ( src = 'Https://code.jquery.com/jquery-2.1.1.min.js' ) [ roteiro ( src = inicializao + 'Js
/' + X )
para X dentro [ ' bootstrap.min.js' , 'Bootstrap-dropdown.js' ]]

com doutor :
com div ( cls = 'recipiente' ):
com h1 ():
perodo ( cls = 'Glyphicon glyphicon-mapa do marcador' )
perodo ( 'Meu ponto' )
com div ( cls = 'linha' ):
com div ( cls = 'Col-sm-6' ):
p ( '{{corpo}}' )
com div ( cls = 'Col-sm-6' ):
p ( 'Avaliar uma expresso:' )
entrada_ ( identidade = 'expresso' , tipo = 'texto' )
boto ( 'Avalie' , cls = 'Btn btn-primrio' )
div ( estilo = 'Margem superior: 10px;' )
com div ( cls = 'suspenso' ):
com boto ( cls = "Btn btn-default suspensa-toggle" ,
tipo = "boto" , data_toggle = 'suspenso' ):
perodo ( 'Suspenso' )
perodo ( cls = 'Acento circunflexo' )

Unid = ( 'Aao' , 'Outra ao' ,


'Mais uma aco' )
ul (( li ( uma ( X , href = '#' )) para X dentro Unid ),
cls = 'menu suspenso' )

com div ( cls = 'linha' ):


h3 ( 'Progresso:' )
com div ( cls = 'progresso' ):
com div ( cls = 'Barra de progresso' , Funo = 'Barra de progresso' ,
estilo = 'Largura: 60%;' ):
perodo ( '60%' )

30 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


com div ( cls = 'linha' ):
para vid dentro [ ' 4vuW6tQ0218' , 'WZZ7oFKsKzY' , 'NfnMJMkhDoQ' ]:
com div ( cls = 'Col-sm-4' ):
com div ( cls = 'Incorporar-responsive incorporar-responsive-16by9' ):
iframe (
cls = 'Incorporar-responsive item' ,
src = 'Https://www.youtube.com/embed/' + vid ,
moldura = '0' )

@rota ( '/' )
def raiz ():
palavra = lambda : '' . Junte-se (
escolha ( ascii_letters ) para Eu dentro alcance ( randint ( 2 , 10 )))
nih_lorem = '' . Junte-se ( palavra () para Eu dentro alcance ( 50 ))
Retorna modelo ( str ( doutor ), corpo = nih_lorem )

E se __nome__ == '__ a Principal__' :

importar enfiando
fio = enfiando . Fio (
alvo = corre , kwargs = dict ( hospedeiro = 'Localhost' , porta = 8080 ),
demnio = Verdade )

fio . comear ()

webview . create_window (
"No um navegador, honesto!" , "Http: // localhost: 8080" ,
largura = 800 , altura = 600 , redimensionvel = Falso )

webview, a estrela do show! A outra estrela do show. dominar permite criar HTML com uma

srie de manipuladores de contexto aninhados. A terceira estrela do show! o garrafa framework

fornece uma interface muito simples para a construo de um aplicativo da web bsico

com placas temperadas e roteamento.

Construo de HTML em Python tem a enorme vantagem de usar todas as ferramentas de

sintaxe da linguagem tem para oferecer. Usando Bootstrap, um dos quadros de front-end

mais antigas e robustas, temos acesso a coisas divertidas como cones glifo. As variveis

do modelo ainda pode ser inserido em nosso HTML e sub-stituted mais tarde utilizando as

ferramentas do quadro web.

Interfaces Grficas | 31
Para demonstrar que realmente temos Bootstrap, aqui um widget pro- gresso bar. Com pywebview,

voc pode, claro, usar qualquer widget Bootstrap, e de fato todas as outras ferramentas

que nor- malmente ser usado em interfaces de usurio do navegador web. Eu j

incorporado alguns vdeos divertidos do YouTube.

A execuo deste programa produz uma grande-olhando interface, como mostrado na Figura 1-6 .

Figura 1-6. A interface bonita e agradvel com muito pouco esforo.

Para esta demonstrao, eu usei o Papel Bootstrap tema, mas alterando uma nica palavra
que voc pode usar um sistema totalmente diferente! o
Super heroi tema Bootstrap mostrado na Figura 1-7 .

32 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


Figura 1-7. O mesmo aplicativo, mas usando o tema super-heri da Bootswatch.

No exemplo anterior foi tambm utilizado o dominar


biblioteca, que um utilitrio prtico para gerar HTML processualmente. No
apenas para tarefas simples: esta demonstrao mostra como ele pode
lidar com atributos Bootstrap e widgets bastante sucesso. dominar trabalha
com gerentes de contexto aninhados para gerenciar o escopo de tags HTML,
enquanto atributos HTML so atribudos com argumentos de palavra-chave.

Para o tipo de aplicao que Pywebview visa, seria muito interessante


para pensar sobre como dominar poderia ser usado para fazer uma
abstrao que com- pletamente esconde tecnologias de navegador
como HTML e JavaScript, e permite criar (por exemplo, clique no
boto-dlers Han-) inteiramente em Python sem se preocupar com o
processamento de eventos intermedirio dentro do motor de JavaScript.
Esta tcnica j explorada em ferramentas existentes como flexx .

Interfaces Grficas | 33
Ferramentas do sistema
Python fortemente usado para fazer ferramentas que trabalham em estreita colaborao com
o sistema operacional, e no deve ser nenhuma surpresa descobrir que existem excelentes
bibliotecas espera de ser descoberto. o psutil biblioteca lhe d todo o acesso ao sistema
operacional e processar informaes que voc poderia esperar, enquanto o co de guarda biblioteca
lhe d ganchos para notificaes de arquivo de eventos do sistema. Finalmente, fechar este
captulo com uma olhada ptpython, que lhe d um prompt Python interativo significativamente
enriquecida.

psutil

Psutil fornece acesso completo a informaes do sistema. Aqui est um exemplo ple sim- de um relatrio

bsico para a carga da CPU recolhidas durante 5 segundos:

importar psutil

CPU = psutil . cpu_percent ( intervalo = 5 , percpu = Verdade )


impresso ( CPU )

Sada:

[ 21,4 , 1,2 , 18,0 , 1,4 , 15,6 , 1.8 , 17,4 , 1,6 ]

Ela produz um valor para cada CPU lgica: no meu computador, oito. O resto do psutil API
to simples e limpo como mostra este exemplo, e a API tambm fornece acesso
memria, disco e informaes do trabalho NETWORKS. Isto muito extenso.

H tambm informaes detalhadas sobre processos. Para demonstrar, aqui um


programa que monitora o seu prprio consumo de memria e joga a toalha quando um
limite atingido:

importar psutil
importar OS , sys , Tempo

pid = OS . getpid ()
p = psutil . Processo ( pid )
impresso ( ' Informaes do processo:' )

impresso ( ' Nome:' , p . nome ())


impresso ( ' exe :' , p . exe ())

dados = []
enquanto Verdade :

dados + = Lista ( alcance ( 100000 ))


informaes = p . memory_full_info ()
# Converter para MB

34 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


memria = informaes . uss / 1024 / 1024

impresso ( ' Memria usada: {:} .2f MB' . formato ( memria ))


E se memria > 40 :
impresso ( ' Memria muito grande! Sair '. )
sys . Sada ()
Tempo . dormir ( 1 )

o OS mdulo na biblioteca padro fornece a identificao do processo (PID).

psutil constri um Processo() objeto com base no PID. Neste caso, o PID o nosso

prprio, mas poderia ser qualquer processo em execuo no sistema.

Isso parece ruim: um loop infinito e uma lista cada vez maior! Sada:

informaes do processo :

nome : exe Python : / usr / local / Poro /.../ Memria Python


usado : 11,82 Memria MB usado : 14,91 Memria MB usado : 18,77
Memria MB usado : 22,63 Memria MB usado : 26,48 Memria
MB usado : 30.34 Memria MB usado : 34.19 Memria MB usado :
38.05 Memria MB usado : 41.90 MB de memria muito grande ! saindo
.

O caminho completo foi encurtada aqui para melhorar o ance aparecimentos


do trecho. H muitos mais mtodos alm nome
e exe disponvel em psutil.Process () instncias. O tipo de memria mostrado aqui
o tamanho nico set, que a memria real liberada quando esse processo termina.
O relato do tamanho nico conjunto um novo recurso na verso 4 psutil, que
tambm funciona no Windows.

H um extenso conjunto de propriedades do processo pode interrogar com psutil, e eu


encorajo voc a ler a documentao. Uma vez que voc comear a usar psutil, voc vai
descobrir mais e mais cenrios em que ele pode fazer sentido para capturar
propriedades do processo. Por exem- plo, pode ser til, dependendo da sua aplicao,
para capturar

Ferramentas do sistema
| 35
processar informaes dentro de manipuladores de exceo para que seu registro de erros pode
incluir informaes sobre carga de CPU e memria.

co de guarda

co de guarda uma alta qualidade, biblioteca multi-plataforma para receber es noti- de

mudanas no sistema de arquivos. Tais notificaes do sistema de arquivos um requisito


fundamental em muitas aplicaes de automao e
co de guarda lida com todos os de baixo nvel e multi-plataforma detalhes de notificaes de

eventos do sistema. E, a grande coisa sobre co de guarda


que ele no usa polling.

O problema com polling que ter muitos desses processos Run- ning s vezes pode
consumir mais recursos do que voc pode ser ing dispostas a participar com,
especialmente em sistemas de baixa-spec, como o
Raspberry Pi . Ao utilizar os sistemas de notificao nativas em cada plata- forma,
o sistema operacional diz lhe imediatamente quando algo mudou, ao invs de voc
ter que pedir. No Linux, o inotify
API usado; no Mac OS X, ou kqueue ou FSEvents so usados; e no Windows, o ReadDirectoryChangesW
API usado. co de guarda
permite-lhe escrever cdigo multi-plataforma e no se preocupar muito sobre como a
salsicha feita.

co de guarda tem uma API maduro, mas uma maneira de obter uso imediato com isso usar o

incluiu watchmedo utilitrio de linha de comando para executar um comando shell quando algo
muda. Aqui esto algumas idias para inspirao:

Compilando modelo e marcao idiomas:

# Linguagem compilada modelo Jade em HTML


$ watchmedo shell de comandos \
- - padres = "* .jade" \
- - comando = 'Pyjade -c jinja "$ {watch_src_path}"' \
- - ignor-diretrios

# Converter um asciidoc para HTML


$ watchmedo shell de comandos \
- - padres = "* .asciidoc" \
- - comando = 'Asciidoctor "$ {watch_src_path}"' \
- - ignor-diretrios

Watchdog ir substituir o nome do arquivo alterado especfico usando este nome


do modelo.

36 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


As tarefas de manuteno, como backups ou espelhamento:

# Sincronizar arquivos para um servidor


$ watchmedo shell de comandos \
- - padres = "*" \
- - comando = 'Rsync -avz mydir / host: / home / ubuntu "'

tarefas de convenincia, como formatadores que funcionam automaticamente, fiapos ERS e exames:

# formatar automaticamente o cdigo-fonte Python para PEP8 (!)


$ watchmedo shell de comandos \
- - padres = "* .py" \
- - comando = 'Pyfmt -i "$ {watch_src_path}"' \
- - ignor-diretrios

Chamando terminais de API na Web, ou at mesmo enviar e-mails e mensagens SMS:

# Envie para um arquivo de cada vez que muda!


$ watchmedo shell de comandos \
- - padres = "*" \
- - comando = ' "$ {watch_src_path}" gato |
-mail -s "Nova verso" me@domain.com' \
- - ignor-diretrios

A API de co de guarda como uma biblioteca bastante semelhante interface de linha de comando
introduzido no incio. Existem as peculiaridades habituais com programao baseada em threads
que voc tem que estar ciente, mas as expresses tpicas so suficientes:

a partir de watchdog.observers importar Observador


a partir de watchdog.events importar (

PatternMatchingEventHandler , FileModifiedEvent ,
FileCreatedEvent )

observador = Observador ()

classe treinador ( PatternMatchingEventHandler ):


def on_created ( auto , evento : FileCreatedEvent ):
impresso ( ' Arquivo Criado: ' , evento . src_path )

def on_modified ( auto , evento : FileModifiedEvent ):


impresso ( ' Arquivo de modificao: % s [ % s ]' % (

evento . src_path , evento . tipo de evento ))

observador . cronograma ( event_handler = treinador ( '*' ), caminho = '' )


observador . demnio = Falso
observador . comear ()

Ferramentas do sistema
| 37
experimentar :

observador . Junte-se ()
exceto KeyboardInterrupt :
impresso ( ' Parado.' )
observador . Pare ()
observador . Junte-se ()

Criar um observador instncia. Voc tem a subclasse um dos treinador classes e substituir

os mtodos de eventos que voc deseja processar. Aqui eu tenho manipuladores

mentadas implementa para criao e modificao, mas existem vrios outros mtodos que

podem fornecer, como explicado no docu- mentao . Voc cronograma o manipulador de

eventos, e dizer co de guarda o que deveria estar assistindo. Neste caso, eu pedi para as

notificaes sobre todos os arquivos

(*) N-a diretrio atual (.).

co de guarda executado em um segmento separado. Chamando o Junte-se()

mtodo, voc pode forar o fluxo do programa para bloquear neste momento. Com esse cdigo

em execuo, eu habilmente executada alguns deles:

$ tocar secrets.txt
$ tocar secrets.txt
$ tocar secrets.txt
[ etc ]

Esta a sada do console da corrida co de guarda demonstrao:

Arquivo Criado: ./secrets.txt arquivo


modificado:. [ modificada ]
Arquivo modificao: ./secrets.txt [ modificada ]
Arquivo modificao: ./secrets.txt [ modificada ]
Arquivo modificao: ./secrets.txt [ modificada ]
Arquivo modificao: ./secrets.txt [ modificada ]
Parado.

Processo terminado com Sada cdigo 0

Aqui eu terminado o programa pressionando Ctrl-C. Como podemos ver, co de guarda vi

todas as modificaes que eu fiz para um arquivo no diretrio sendo vigiado.

38 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


ptpython

ptpython uma interface intrprete alternativa, oferecendo uma bela experincia Python interativo.

Assim sendo, ptpython mais como uma ferramenta de uma biblioteca para incluir em seus prprios
projetos, mas o que uma ferramenta!
Figura 1-8 mostra uma imagem que mostra a interface de utilizador bsica. Quando voc
precisa para trabalhar com blocos no intrprete, como classes e funes, voc vai achar
que o acesso ao histrico de comandos muito mais conveniente do que a interface
intrprete padro: quando voc rola a um comando anterior, o bloco inteiro mostrado, no
s linhas individuais, como mostrado na Figura 1-9 .

Aqui, I recuperado o cdigo para a declarao de funo pressionando a seta para cima (ou

Ctrl-p) e todo o bloco mostrado, em vez de ter de se deslocar por meio de linhas

separadamente. As caractersticas adicionais incluem vi e Emacs chaves, apoio theming,

insinuando docstring, e de validao de entrada, que verifica um comando (ou bloco) para erros

de sintaxe antes de permitir avaliao. Para ver o conjunto completo de opes configurveis,

pressione F2, como visto na A Figura 1-10 .

Figura 1-8. As sugestes de concluso de cdigo pop-up automaticamente enquanto voc digita.

Ferramentas do sistema
| 39
Figura 1-9. Quando se desloca para as entradas anteriores, blocos inteiros so sugerido (por exemplo, a

funo f ()), no apenas linhas simples.

Figura 1-10. O menu de configuraes acessveis atravs de F2.

40 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


Na linha de comando, ptpython oferece recursos altamente produtivos que so certo para
melhorar o seu fluxo de trabalho. Descobri que ptpython
a maneira mais rpida para testar rapidamente alguma sintaxe ou uma chamada de biblioteca,
sem ter que abrir um editor ou ente de desenvolvimento integrado am- (IDE). E se voc preferir IPython,
voc vai ficar feliz em saber que
ptpython inclui uma integrao que pode ser iniciada com thon ptipy. Isso torna
disponvel a integrao shell que IPython ofertas, assim como a sua riqueza de
comandos mgicos.

APIs Web com abrao


Python notoriamente usado em um grande nmero de frameworks web, e uma extenso
desta rea o domnio de servios web em que APIs esto expostos a programas de outros
usurios para consumir. Neste domnio,
framework Django RESTO e frasco so escolhas muito populares, mas voc ainda no pode ter
ouvido de abrao.

abrao uma biblioteca que fornece uma maneira extremamente simples para criar APIs da
Internet para servios web. Ao explorar alguns dos recursos de linguagem de Python, grande
parte do clich habitual normalmente exigido quando APIs criando para servios web
removido.

Aqui est um pequeno servio web que converte entre o valor hexadecimal de uma cor e sua nome
CSS3 :

importar abrao

importar tripleto hexadecimal

@ hug.get ()
def hextoname ( feitio : abrao . tipos . texto ):
Retorna tripleto hexadecimal . hex_to_name ( '#' + feitio )

@ hug.get ()
def nametohex ( nome : abrao . tipos . texto ):
Retorna tripleto hexadecimal . name_to_hex ( nome )

Tambm estamos usando o tripleto hexadecimal biblioteca aqui: o seu


balco nico para a converso de cores web segura entre formatos vari-
ous como nome, hex, e rgb. No se esquea que voc tambm pode
converter entre rgb e outros formatos como hsl com o colorsys biblioteca que
j est includo na biblioteca padro Python!

APIs Web com abrao | 41


No abrao exemplo, fizemos pouco mais que envolva duas funes do tripleto
hexadecimal pacote: um para converter de hex para nome e um para fazer o oposto.
difcil de acreditar no incio, mas os
@ hug.get decoradores so tudo que voc precisa para comear a API bsica. O servidor iniciado

usando a incluiu abrao ferramenta de linha de comando ( A Figura 1-11 ).

Figura 1-11. Abrao vai um longo caminho para que se sinta bem-vindo.

E isso! Podemos imediatamente testar a nossa API. Voc poderia usar um navegador web para isso,

mas fcil o suficiente para usar uma ferramenta como ondulao. Voc chamar o endpoint URL com os

parmetros corretos, e abrao retorna a resposta:

$ http curl: // localhost: 8000 / hextoname hex = ff0000

"vermelho"

$ http curl: // localhost: 8000 / nametohex nome = Lightskyblue

"# 87cefa"

42 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


O nome da funo foi hextoname, e o nome do parmetro foi hex. Note que
ns no fornecer o hash, #, como parte dos dados do pedido porque
interfere com a anlise do pedido HTTP.

Esta API tem uma funo ponto final diferente, nametohex, e seu parmetro
chamado nome.

bastante impressionante para obter uma API-se web ao vivo com to pouco trabalho. E os
recursos no param por a: abrao gera automaticamente API docu- mentao, que o que voc
ganha ao omitir um ponto final:

$ http onda: // localhost: 8000 /


{
"404" : "A API chamar voc tentou fazer no foi definida. Eis
uma definio da API para ajud-lo a ir :)" ,
"documentao" : {
"manipuladores" : {
"/ Hextoname" : {
"OBTER" : {
"outputs" : {
"formato" : "JSON (JavaScript Serialized
Object Notation)" ,
"tipo de contedo" : "Application / json"
},
"inputs" : {
"Hex" : {
"tipo" : "Text valor bsico / string"
}}}}
,

"/ Nametohex" : {
"OBTER" : {
"outputs" : {
"formato" : "JSON (JavaScript Serialized
Object Notation)" ,
"tipo de contedo" : "Application / json"
},
"inputs" : {
"nome" : {
"tipo" : "Text valor bsico / string"
}}}}}}}

APIs Web com abrao | 43


Os tipos dos parmetros que especificados com hug.types.text so usados no apenas para a

documentao, mas tambm para converses de tipo. Se estas eram todas as caractersticas

fornecidas pelo abrao, j seria o suficiente para muitas tarefas API; No entanto, uma das melhores

caractersticas do abrao que ele automaticamente lida com verses. Considere o seguinte

exem- plo:

importar abrao

importar inflectir
motor = inflectir . motor ()

@ hug.get ( verses = 1 )
def singular ( palavra : abrao . tipos . texto ):
"" "Retorna a verso singular da palavra ''"
Retorna motor . pronome singular ( palavra ) . mais baixo ()

@ hug.get ( verses = 1 )
def plural ( palavra : abrao . tipos . texto ):
"" "Retorna a verso plural da palavra ''"
Retorna motor . plural ( palavra ) . mais baixo ()

@ hug.get ( verses = 2 )
def singular ( palavra : abrao . tipos . texto ):
"" "Retorna o singular da palavra, preservando caso ''"
Retorna motor . pronome singular ( palavra )

@ hug.get ( verses = 2 )
def plural ( palavra : abrao . tipos . texto ):
"" "Retorna o plural da palavra, preservando caso ''"
Retorna motor . plural ( palavra )

Este novo abrao API envolve o inflectir pacote, que fornece ferramentas para
manipulao palavra.

A primeira verso da API retorna em minsculas resultados. A segunda verso, mais

recente do mesma API retorna o resultado como calculada pela flexionar, sem qualquer

alterao.

Tambm estamos usando o inflectir biblioteca, o que torna um nmero


enorme de transformaes palavra possveis, incluindo pluralizao, a
transformao de gnero dos substantivos pr, contando ( houve
erro versus houve erros), seleo de artigos correta ( a, um, e
a), algarismos romanos, e muito mais!

44 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


Imagine que ns criamos este servio web para fornecer uma API para transformar palavras
em sua verso singular ou no plural: uma ma, mas, e assim por diante. Por alguma
razo que agora nos escapa, no primeiro lanamento, em minsculas os resultados antes
de retorn-los:

$ http curl: // localhost: 8000 / v1 / singular / word = 20Walks parvos%

"Caminhada bobo"

$ http curl: // localhost: 8000 / v1 / plural palavra = Crise

"crises"

Nota: o URL agora tem um especificador v1 para a verso 1. No nos ocorreu que
alguns usurios podem preferir para ter o caso de palavras de entrada preservados: por
exemplo, se uma palavra no incio de uma sentena est sendo alterada, seria melhor para
preservar a o capitaliza-. Felizmente, o inflectir biblioteca j faz isso por padro, e abrao fornece
controle de verso que permite-nos fornecer uma segunda sion ver- da API (de modo a no
ferir os usurios existentes que podem esperar a transformao minscula):

$ http curl: // localhost: 8000 / v2 / singular / word = 20Walks parvos%

"Parva Walk"

$ http curl: // localhost: 8000 / v2 / plural / word = Crise

"Crises"

Essas chamadas de API usar a verso 2 do nosso servio web. E, finalmente, a documentao
tambm controle de verso, e para este exemplo, voc pode ver como a funo docstrings tambm
so incorporados como texto de uso:

$ http onda: // localhost: 8000 / v2 /


{
"404" : "A API chamar voc tentou fazer no foi definida. Eis
uma definio da API para ajud-lo a ir :)" ,
"documentao" : {
"verso" : 2,
"verses" : [
1, 2

],
"manipuladores" : {
"/singular" : {

APIs Web com abrao | 45


"OBTER" : {
"uso" : "Devolver o singular da palavra,
preservando caso " ,
"outputs" : {
"formato" : "JSON (JavaScript Serialized
Object Notation)" ,
"tipo de contedo" : "Application / json"
},
"inputs" : {
"palavra" : {
"tipo" : "Text valor bsico / string"
}}}}
,

[ recorte... ]

Cada verso tem documentao separada, e chamando que endpoint verso, ou

seja, v2, retorna a documentao para que sion ver-. o docstring de cada funo

reutilizado como o texto de uso para essa chamada API.

abrao tem extensa documentao em que h mesmo turas mais FEA para descobrir.
Com o interesse explodindo em aplicaes internet-de-coisas, provvel que as
bibliotecas simples e poderosas como abrao
ir desfrutar de grande popularidade.

Datas e Horrios
Muitos usurios de Python citar dois pontos de dor principais: o primeiro embalagem,

e para isso ns cobrimos voar em um captulo anterior. O segundo est trabalhando com
datas e horrios. Neste captulo, cobrir duas bibliotecas que vai fazer uma enorme diferena
na forma como voc lida com tempo- assuntos ral. flecha uma biblioteca reinventados para
trabalhar com data hora
objetos nos quais fusos horrios esto sempre presentes, o que ajuda a mini- mize uma grande
classe de erros que novos programadores Python ocorrer com freqncia. ParseDateTime uma
biblioteca que permite que o cdigo de anlise entradas de linguagem natural para datas e horas,
o que pode torn-lo muito mais fcil para os usurios a fornecer tais informaes.

46 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


flecha

Embora as opinies divergem, h aqueles que tm encontrado da biblioteca dard Standards


data hora mdulo confuso para usar. O mdulo de docu- mentao-se no primeiros

pargrafos explica porqu: ele fornece tanto ingnuo e consciente objetos para representar
datas e horrios. o ingnuo
ones so a fonte de confuso, porque os desenvolvedores de aplicativos cada vez mais

encontram-se a trabalhar em projectos em que zonas de tempo-so criticamente importantes. O

aumento dramtico da nuvem infra- aplicaes ture e software-as-a-service tm contribudo para

a realidade de que sua aplicao vai freqentemente executados em uma regio tempo- diferente

(por exemplo, em um servidor) de onde os desenvolvedores esto localizados, e diferen- rentes

novamente para onde os usurios esto localizados. o ingnuo data hora objetos so os que voc

costuma ver em demos e tutoriais:

importar data hora

dt = data hora . data hora . agora ()


dt_utc = data hora . data hora . UtcNow ()
diferena = ( dt - dt_utc ) . total_seconds ()

impresso ( ' diferena Total: % .2f segundos % diferena )

Este cdigo no poderia ser mais simples: ns criamos dois data hora objetos, e calcular a
diferena. O problema que ns provavelmente destinado tanto agora() e UtcNow () significar agora
como em neste momento, mas talvez em diferentes fusos horrios. Quando a diferena
calculada, ns temos o que parece uma absurdamente grande resultado:

Total diferena : 36000.00 segundos

A diferena , de fato, a diferena de fuso horrio entre a minha localizao


atualizadas e UTC: +10 horas. Este resultado o pior tipo de incorreto porque ,
de fato, um lugar para outro Se fusos horrios no so tidos em conta; e aqui reside a
raiz do problema: a incompreenso do que as funes realmente fazem. o agora() e UtcNow
()
funes Faz retornar o tempo atual em fusos horrios locais e UTC, mas infelizmente ambos

os resultados so ingnuo data hora objetos e fore l- carecem de dados de fuso horrio.

Note-se que possvel criar data hora objetos com dados de fuso horrio em anexo, ainda que

de forma subjectiva complicado: voc cria uma

consciente data hora definindo o tzinfo atribuir zona de tempo- correcta. No nosso
exemplo, poderamos (e deve!) Criaram uma corrente

Datas e Horrios | 47
data hora objeto da seguinte maneira, por passagem do fuso horrio para o agora() funo:

dt = data hora . data hora . agora ( tz = data hora . fuso horrio . UTC )

Claro, se voc fizer essa alterao na linha 3 e tentar executar novamente o cdigo,
aparece o seguinte erro:

TypeError: pode ' datetimes t subtrair-offset ingnuo e


compensar-aware

Isso acontece porque, embora o UtcNow () produz uma funo data hora para o fuso
horrio UTC, o resultado um ingnuo data hora
objeto, e Python impede de mistura ingnuo e consciente data hora objetos. Se de
repente voc est com medo de trabalhar com datas e horrios, isso uma resposta
compreensvel, mas eu prefiro incentiv-lo a ser em vez medo de datetimes que os dados
de falta de fuso horrio. o
TypeError apenas mostrado o tipo de erro que realmente quer: ela nos obriga a garantir que todo

o nosso data hora casos so consciente.

Naturalmente, para lidar com isso no caso geral requer algum tipo de banco de dados de
fusos horrios. Infelizmente, exceto para UTC, a biblioteca padro do Python no inclui
dados de fuso horrio; em vez disso, a recomendao usar uma biblioteca mantida
separadamente chamado pytz , E se voc precisa trabalhar com datas e horrios,
encorajo-vos vivamente a investigar essa biblioteca com mais detalhes.

Agora podemos finalmente mergulhar no tema principal desta seo, que


flecha: uma biblioteca de terceiros que oferece uma API muito mais simples para trabalhar com

datas e horrios. Com flecha, tudo tem uma zona de tempo- ligado (e , portanto, conscientes):

importar flecha

t0 = flecha . agora ()
impresso ( t0 )

t1 = flecha . UtcNow ()
impresso ( t1 )

diferena = ( t0 - t1 ) . total_seconds ()

impresso ( ' diferena Total: % .2f segundos % diferena )

48 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


Sada:

2016-06-26T18: 43: 55.328561 + 10: 00


2016-06-26T08: 43: 55.328630 + 00: 00
diferena total: -0.00 segundos

Como voc pode ver, o agora() funo produz a data e hora atual com meu fuso
horrio local ligada (UTC + 10), enquanto o utc agora () funo Alm disso produz a
data atual e tempo, mas com o fuso horrio UTC anexado. Como consequncia,
a diferena efectiva entre os dois tempos assim que deve ser: zero. E o
delicioso flecha biblioteca s fica melhor de l. Os prprios objetos tm atributos e
mtodos que voc esperaria convenientes:

> > > t0 = flecha . agora ()


> > > t0
< Flecha [ 2016 - 06 - 26 T18 : 59 : 07.691803 + 10 : 00 ] >

> > > t0 . encontro ()


data hora . encontro ( 2016 , 6 , 26 )

> > > t0 . Tempo ()


data hora . Tempo ( 18 , 59 , 7 , 691803 )

> > > t0 . timestamp


1466931547

> > > t0 . ano


2016

> > > t0 . ms


6

> > > t0 . dia


26

> > > t0 . datetime datetime . data hora ( 2016 , 6 , 26 , 18 , 59 , 7 , 691803 ,

tzinfo = tzlocal ())

Note-se que o data hora produzido a partir do mesmo atributo carrega corretamente as
informaes essenciais fuso horrio.

Existem vrias outras caractersticas do mdulo que voc pode ler mais sobre no a
documentao , Mas esta ltima caracterstica proporciona uma segue apropriado para a
prxima seo:

Datas e Horrios | 49
> > > t0 = flecha . agora ()
> > > t0 . humanizar ()
'Agora mesmo'
> > > t0 . humanizar ()
'segundos atrs'

> > > t0 = t0 . substituir ( horas = - 3 , minutos = 10 )


> > > t0 . humanizar ()
'2 horas atrs'

A humanizao mesmo foi construdo com suporte para vrios locais!

> > > t0.humanize (localidade = 'ko') '2


'
> > > t0.humanize (localidade = 'ja') '2
'
> > > t0.humanize (localidade = 'hu') '2
ezeltt rval'
> > > t0.humanize (localidade = 'de') 'vor
2 Stunden'
> > > t0.humanize (localidade = 'FR') 'il ya
2 heures'
> > > t0.humanize (localidade = 'El') '2
'
> > > t0.humanize (localidade = 'oi') '2
'
> > > t0.humanize (localidade = 'zh') '2
'

bibliotecas alternativas para datas e horrios

Existem vrias outras excelentes bibliotecas para lidar com datas


e horas em Python, e seria vale a pena conferir tanto Delorean eo
muito novo Pendu- lum biblioteca.

ParseDateTime

ParseDateTime uma biblioteca maravilhosa, com um foco dedicado: pars- ing texto em

datas e horrios. Como seria de esperar, pode ser obtida com pip instalar ParseDateTime. o documentao
oficial muito API-like, que torna mais difcil do que deveria ser para obter uma viso
geral do que as ofertas da biblioteca, mas voc pode obter uma boa idia do que est
disponvel ao navegar pela extensa sute de teste . O mnimo que voc deve esperar de
um data hora- analisar biblioteca para lidar com os formatos mais comuns, e o exemplo
de cdigo a seguir demonstra isso:

50 | Captulo 1: expandir o seu conhecimento Python: Bibliotecas menos conhecidos


importar ParseDateTime Como PDT

cal = PDT . Calendrio ()

exemplos = [
"2016/07/16" ,
"2016/07/16" ,
"2016/07/16" ,
"2016/07/16" ,
"2016/07/16" ,
"2016/07/16" ,
"7-16-16" ,
"7/16/16" ,
]

impresso ( '{: 30} {:> 30}' . formato ( 'Entrada' , 'Resultado' ))


impresso ( '=' * 60 )
para e dentro exemplos :

dt , resultado = cal . parseDT ( e )


impresso ( '{: < 30} {:> 30}' . formato ( '"' + e + '"' , dt . ctime ()))

Isso produz o seguinte e surpreendente, de sada:

Entrada Resultado

================================================== ==========
"2016/07/16" Sat julho 16 16:25:20 2016
"2016/07/16" Sat julho 16 16:25:20 2016
"2016/07/16" Sat julho 16 16:25:20 2016
"2016/07/16" Sat julho 16 16:25:20 2016
"2016/07/16" Sat julho 16 16:25:20 2016
"2016/07/16" Sat julho 16 16:25:20 2016
"7-16-16" Sat julho 16 16:25:20 2016
"7/16/16" Sat julho 16 16:25:20 2016

Por padro, se o ano dado ltimo, ento ms dia ano Assume-se, e a biblioteca
tambm lida com convenientemente a presena ou ausncia de zeros, bem como se
hfens (-) ou barras (/) so usados como delimitadores.

Significativamente mais impressionante, porm, como ParseDateTime dles Han- mais


complicadas, linguagem natural entradas:

importar ParseDateTime Como PDT

a partir de data hora importar data hora

cal = PDT . Calendrio ()

exemplos = [
"19 de novembro de 1975" ,
"19 de novembro de 75" ,
"Novembro 19, 75" ,

Datas e Horrios | 51
"amanh" ,
"ontem" ,
"10 minutos a partir de agora" ,
"O primeiro de janeiro de 2001" ,
"3 dias atrs" ,
"Vez em quatro dias" ,
"Daqui a duas semanas" ,
"trs meses atrs" ,
"2 semanas e 3 dias no futuro" ,
]

impresso ( ' Now: {}' . format ( datetime . now () . ctime ()), end = '\ n\n' )
print ( '{: 40s}{:>30s}' . format ( 'Input' , 'Result' ))
print ( '=' * 70 )
for e in examples :
dt , result = cal . parseDT ( e )
print ( '{:< 40s}{:>30}' . format ( '"' + e + '"' , dt . ctime ()))

Incredibly, this all works just as youd hope:

Now: Mon Jun 20 08:41:38 2016

Input Result
================================================================
"19 November 1975" Wed Nov 19 08:41:38 1975
"19 November 75" Wed Nov 19 08:41:38 1975
"19 Nov 75" Wed Nov 19 08:41:38 1975
"tomorrow" Tue Jun 21 09:00:00 2016
"yesterday" Sun Jun 19 09:00:00 2016
"10 minutes from now" Mon Jun 20 08:51:38 2016
"the first of January, 2001" Mon Jan 1 08:41:38 2001
"3 days ago" Fri Jun 17 08:41:38 2016
"in four days' time" Fri Jun 24 08:41:38 2016
"two weeks from now" Mon Jul 4 08:41:38 2016
"three months ago" Sun Mar 20 08:41:38 2016
"2 weeks and 3 days in the future" Thu Jul 7 08:41:38 2016

The urge to combine this with a speech-to-text package like Speech Recognition or
watson-word-watcher (which provides confidence values per word) is almost
irresistible, but of course you dont need complex projects to make use of parsedatetime:
even allowing a user to type in a friendly and natural description of a date or time
interval might be much more convenient than the usual but frequently clumsy DateTimePicker
widgets weve become accus tomed to.

52 | Chapter 1: Expanding Your Python Knowledge: Lesser-Known Libraries


Another library featuring excellent datetime parsing abilities is Chronyk
.

General-Purpose Libraries
In this chapter we take a look at a few batteries that have not yet been included in
the Python standard library, but which would make excellent additions.

General-purpose libraries are quite rare in the Python world because the standard
library covers most areas sufficiently well that library authors usually focus on very
specific areas. Here we discuss
boltons ( a play on the word builtins), which provides a large num ber of useful
additions to the standard library. We also cover the
Cython library, which provides facilities for both massively speeding up Python code,
as well as bypassing Pythons famous global inter preter lock ( GIL) to enable true
multi-CPU multi-threading.

boltons

The boltons library is a general-purpose collection of Python mod ules that covers a
wide range of situations you may encounter. The library is well-maintained and
high-quality; its well worth adding to your toolset.

As a general-purpose library, boltons does not have a specific focus. Instead, it


contains several smaller libraries that focus on specific areas. In this section I will
describe a few of these libraries that bol tons offers.

boltons.cacheutils

boltons.cacheutils provides tools for using a cache inside your code. Caches are very
useful for saving the results of expensive oper ations and reusing those previously
calculated results. The functools module in the standard library already provides a
decorator called lru_cache, which can be used to memoize calls: this means that the
function remembers the parameters from previous calls, and when the same
parameter values appear in a new call, the previous answer is returned directly,
bypassing any calculation.

General-Purpose Libraries | 53
boltons provides similar caching functionality, but with a few con venient tweaks.
Consider the following sample, in which we attempt to rewrite some lyrics from
Taylor Swifts 1989 juggernaut record. We will use tools from boltons.cacheutils to
speed up processing time:

import json
import shelve
import atexit
from random import choice
from string import punctuation
from vocabulary import Vocabulary as vb

blank_space = """
Nice to meet you, where you been? I could show
you incredible things Magic, madness, heaven, sin
Saw you there and I thought Oh my God, look at
that face You look like my next mistake Love's a
game, wanna play?

New money, suit and tie I can read you like a magazine Ain't it
funny, rumors fly And I know you heard about me So hey, let's
be friends I'm dying to see how this one ends Grab your
passport and my hand I can make the bad guys good for a
weekend """

from boltons.cacheutils import LRI , LRU , cached

# Persistent LRU cache for the parts of speech


cached_data = shelve . open ( 'cached_data' , writeback = True )
atexit . register ( cached_data . close )

# Retrieve or create the "parts of speech" cache


cache_POS = cached_data . setdefault (
'parts_of_speech' , LRU ( max_size = 5000 ))

@cached ( cache_POS )
def part_of_speech ( word ):
items = vb . part_of_speech ( word . lower ())
if items :
return json . loads ( items )[ 0 ][ 'text' ]

# Temporary LRI cache for word substitutions

54 | Chapter 1: Expanding Your Python Knowledge: Lesser-Known Libraries


cache = LRI ( max_size = 30 )

@cached ( cache )
def synonym ( word ):
items = vb . synonym ( word )
if items :
return choice ( json . loads ( items ))[ 'text' ]

@cached ( cache )
def antonym ( word ):
items = vb . antonym ( word )
if items :
return choice ( items [ 'text' ])

for raw_word in blank_space . strip () . split ( ' ' ):


if raw_word == '\ n' :
print ( raw_word )
continue
alternate = raw_word # default is the original word.
# Remove punctuation
word = raw_word . translate (
{ ord ( x ): None for x in punctuation })
if part_of_speech ( word ) in [ ' noun' , 'verb' ,
'adjective' , 'adverb' ]:
alternate = choice (( synonym , antonym ))( word ) or raw_word
print ( alternate , end = ' ' )

Our code detects parts of speech in order to know which lyrics to change.

Looking up words online is slow, so we create a small database using the shelve

module in the standard library to save the cache data between runs. We use

the atexit module, also in the standard library, to make sure that our parts of

speech cache data will get saved when the program exits. Here we obtain the LRU

cache provided by boltons.cacheutils

that we saved from a previous run. Here we use the @ cache decorator
provided by boltons.cacheu tils to enable caching of the part_of_speech() function
call. If the word argument has been used in a previous call to this function, the
answer will be obtained from the cache rather than a slow call to the Internet.

General-Purpose Libraries | 55
For synonyms and antonyms, we used a different kind of cache, called a least
recently inserted cache (this choice is explained later in this section). An LRI
cache is not provided in the Python Standard Library.

Here we restrict which kinds of words will be substituted.

The excellent vocabulary package is used here to pro vide access


to synonyms and antonyms. Install it with
pip install vocabulary.

For brevity, Ive included only the first verse and chorus. The plan is staggeringly
unsophisticated: were going to simply swap words with either a synonym or
antonym, and which is decided randomly! Iter ation over the words is
straightforward, but we obtain synonyms and antonyms using the vocabulary package,
which internally calls APIs on the Internet to fetch the data. Naturally, this can be
slow since the lookup is going to be performed for every word, and this is why a
cache will be used. In fact, in this code sample we use two dif ferent kinds of
caching strategies.

boltons.cacheutils offers two kinds of caches: the least recently used ( LRU) version,
which is the same as functools.lru_cache,
and a simpler least recently inserted ( LRI) version, which expires entries based on
their insertion order. In our code, we use an LRU cache to keep a record of the parts
of speech lookups, and we even save this cache to disk so that it can be reused in
successive runs. We also use an LRI cache to keep a record of word substitutions.
For example, if a word is to be swapped with its antonym, the replace ment will be
stored in the LRI cache so that it can be reused. How ever, we apply a very small
limit to the setting for maximum size on the LRI cache, so that words will fall out of
the cache quite regularly. Using an LRI cache with a small maximum size means that
the same word will be replaced with the same substitution only locally, say within the
same verse; but if that same word appears later in the song (and that word has been
dropped from the LRI cache), it might get a different substitution entirely.

56 | Chapter 1: Expanding Your Python Knowledge: Lesser-Known Libraries


The design of the caches in boltons.cacheutils is great in that it is easy to use the
same cache for multiple functions, as we do here for the synonym() and antonym() functions.
This means that once a word substitution appears in the cache, a call to either function
returns the predetermined result from the same cache. Here is an example of the
output:

Nice to meet you, wherever you been? I indeed conduct


you astonishing things Magic, madness, Hell sin Saw you
be and I thought Oh my God, seek at who face You seek
same my following mistake Love's a game, wanna play?

New financial satisfy both tie I be able read you like


a magazine Ain't it funny, rumors fly

And gladly can you heard substantially me So hey, let's


inclination friends I'm nascent to visit whatever that one ends
Grab your passport in addition my hand

I can take the bad guys ill in exchange for member weekend

On second thought, perhaps the original was best after all! It is worth noting just
how much functionality is possible with a tiny amount of code, as long as the
abstractions available to you are pow erful enough.

boltons has many features and we cannot cover everything here; however, we can
do a whirlwind tour and pick out a few notable APIs that solve problems frequently
encountered, e.g., in StackOver flow questions.

boltons.iterutils

boltons.iterutils.chunked_iter(src, size) returns pieces of the source iterable in size- sized


chunks (this example was copied
from the docs ):

> > > list ( chunked_iter ( range ( 10 ), 3 ))


[[ 0 , 1 , 2 ], [ 3 , 4 , 5 ], [ 6 , 7 , 8 ], [ 9 ]]

A similar requirement that often comes up is to have a moving win dow (of a
particular size) slide over a sequence of data, and you can use boltons.iterutils.windowed_iter
for that:

General-Purpose Libraries | 57
> > > list ( windowed_iter ( range ( 7 ), 3 ))
[( 0 , 1 , 2 ), ( 1 , 2 , 3 ), ( 2 , 3 , 4 ), ( 3 , 4 , 5 ), ( 4 , 5 , 6 )]

Note that both chunked_iter() and windowed_iter() can operate on iterables, which
means that very large sequences of data can be processed while keeping memory
requirements tolerable for your usage scenario.

boltons.fileutils

The copytree() function alleviates a particularly irritating behavior of the standard


librarys shutil.copytree() function: Boltons copy tree() will not complain if some or all of
the destination file-system tree already exists. The boltons.fileutils.AtomicSaver context
manager helps to make sure that file-writes are protected against corruption . It
ach ieves this by writing file data to temporary, or intermediate files, and then
using an atomic renaming function to guarantee that the data is consistent. This is
particularly valuable if there are multiple read ers of a large file, and you want to
ensure that the readers only ever see a consistent state, even though you have a
(single!) writer chang ing the file data.

boltons.debugutils

If youve ever had a long-running python application, and wished that you could
drop into an interactive debugger session to see what was happening, boltons.debugutils.pdb_on_signal()
can make that happen. By default, a KeyboardInterrupt handler is automati cally set
up, which means that by pressing Ctrl-C you can drop immediately into the
debugger prompt. This is a really great way to deal with infinite loops if your
application is difficult to debug from a fresh start otherwise.

boltons.strutils

There are several functions in boltons.strutils that are enor mously useful:

slugify(): modify a string to be suitable, e.g., for use as a file name, by


removing characters and symbols that would be inva lid in a filename.

58 | Chapter 1: Expanding Your Python Knowledge: Lesser-Known Libraries


ordinalize(): given a numerical value, create a string referring to its position:

> > > print ( ordinalize ( 1 ))


1 st
> > > print ( ordinalize ( 2 ))
2 nd

cardinalize: given a word and a count, change the word for plurality and preserve
case:

> > > cardinalize ( 'python' , 99 )


'pythons'
> > > cardinalize ( 'foot' , 6 )
'feet'
> > > cardinalize ( 'Foot' , 6 )
'Feet'
> > > cardinalize ( 'FOOT' , 6 )
'FEET'
> > > 'blind ' + cardinalize ( 'mouse' , 3 )
'blind mice'

singularize and pluralize:

> > > pluralize ( 'theory' )


'theories'
> > > singularize ( 'mice' )
'mouse'

bytes2human: convert data sizes into friendler forms:

> > > bytes2human ( 1e6 )


'977K'
> > > bytes2human ( 20 )
'20B'
> > > bytes2human ( 1024 * 1024 )
'1024K'
> > > bytes2human ( 2e4 , ndigits = 2 )
'19.53K'

There are several other useful boltons libraries not mentioned here, and I encourage
you to at least skim the documentation to learn about features you can use in your
next project.

Cython

Cython is a magical tool! As with most magical devices, it is difficult to describe


exactly what it is. Cython is a tool that converts Python

General-Purpose Libraries | 59
source code into C source code; this new code is then compiled into a native binary
that is linked to the CPython runtime. That sounds complicated, but basically Cython
lets you convert your Python modules into compiled extension modules. There are
two main reasons you might need to do this:

You want to wrap a C/C++ library, and use it from Python.

You want to speed up Python code. The second reason is the one Im going to
focus on. By adding a few type declarations to your Python source code, you can

dramatically speed up certain kinds of functions.

Consider the following code, which is as simple as I could possibly make it for this
example:

import array

n = int ( 1e8 )
a = array . array ( 'd' , [ 0.0 ]) * n

for i in range ( n ):
a[i]=i%3

print ( a [: 5 ])

Were using the built-in array module. Set the

size of our data.

Create fictional data: a sequence of double-precision numbers; in reality your

data would come from another source such as an image for image-processing

applications, or numerical data for science or engineering applications. A very

simple loop that modifies our data.

Print the modified data; here, we only show the first five entries. This code
represents the most basic computer processing: data comes in, is transformed, and
goes out. The specific code were using is quite silly, but I hope it is clear enough so
that it will be easy to understand how we implement this in Cython later.

60 | Chapter 1: Expanding Your Python Knowledge: Lesser-Known Libraries


We can run this program on the command line in the following way:

$ time python cythondemoslow.py array ( 'd' , [ 0.0, 1.0,


2.0, 0.0, 1.0 ])

real 0m27.622s
user 0m27.109s
sys 0m0.443s

Ive include the time command to get some performance measure ments. Here we
can see that this simple program takes around 30 seconds to run.

In order to use Cython, we need to modify the code slightly to take advantage of the
Cython compilers features:

import array

cdef int n = int ( 1e8 )


cdef object a = array . array ( 'd' , [ 0.0 ]) * n
cdef double [:] mv = a

cdef int i
for i in range ( n ):
mv [ i ] = i % 3

print ( a [: 5 ])

We import the array module as before. The variable for the data size, n, now gets

a specific datatype. This line is new: we create a memory view of the data inside

the array a. This allows Cython to generate code that can access the data inside

the array directly. As with n, we also specify a type for the loop index i.

The work inside the loop is identical to before, except that we manipulate
elements of the memory view rather than a itself. Having modified our source code
by adding information about native datatypes, we need to make three further
departures from the normal Python workflow necessary before running our
Cython code.

General-Purpose Libraries | 61
The first is that, by convention, we change the file extension of our source-code file
to pyx instead of py, to reflect the fact that our source code is no longer normal
Python. The second is that we must use Cython to compile our source code into a
native machine binary file. There are many ways to do this depending on your
situation, but here were going to go with the simple option and use a
command-line tool provided by Cython itself:

$ cythonize -b -i cythondemofast.pyx

Running this command produces many lines of output messages from the compiler,
but when the smoke clears you should find a new binary file in the same place as
the . pyx file:

$ ls -l cythondemofast.cpython-35m-darwin.so
- rwxr-xr-x@ calebhattingh 140228 3 Jul 15:51
cythondemofast.cpython-35m-darwin.so

This is a native binary that Cython produced from our slightly modified Python
source code! Now we need to run it, and this brings us to the third departure from
the normal Python workflow: by default, Cython makes native extensions ( as
shared libraries), which means you have to import these in the same way you
might import other Python extensions that use shared libraries. With the first
version of our example in ordinary Python, we could run the program easily with python
cythondemoslow.py. We can run the code in our compiled Cython version simply by importing

the native extension. As before, we include the time for measure ment:

$ time python -c "import cythondemofast"


array ( 'd' , [ 0.0, 1.0, 2.0, 0.0, 1.0 ])

real 0m0.751s
user 0m0.478s
sys 0m0.270s

The Cython program gives us a speed-up over the plain Python pro gram of almost
40 times! In larger numerical programs where the time cost of start-up and other
initialization is a much smaller part of the overall execution time, the speed-up is
usually more than 100 times!

In the example shown here, all our code was set out in the module itself, but
usually you would write functions and after compiling

62 | Chapter 1: Expanding Your Python Knowledge: Lesser-Known Libraries


with Cython, and then import these functions into your main Python program.
Heres how Cython can easily integrate into your normal Python workflow:

1. Begin your project with normal Python.

2. Benchmark your performance.

3. If you need more speed, profile your code to find the functions
that consume most of the time.

4. Convert these functions to Cython functions, and compile the new . pyx Cython
modules into native extensions.

5. Import the new Cython functions into your main Python pro gram.

Multithreading with Cython

It wont take long for a newcomer to the Python world to hear about Pythons so-called
GIL, a safety mechanism Python uses to decrease the possibility of problems when
using threads.

Threading is a tool that lets you execute different sections of code in


parallel, allowing the operating system to run each section on a sep arate CPU. The
GIL problem is that the safety lock that prevents the interpreter state from being
clobbered by parallel execution also
has the unfortunate effect of limiting the ability of threads to actually run on
different CPUs. The net effect is that Python threads do not achieve the parallel
performance one would expect based on the availability of CPU resources.

Cython gives us a way out of this dilemma, and enables multithread ing at full
performance. This is because native extensions ( which is what Cython makes) are
allowed to tell the main Python interpreter that they will be well-behaved and dont
need to be protected with the global safety lock. This means that threads containing
Cython code can run in a fully parallel way on multiple CPUs; we just need to ask
Python for permission.

In the following code snippet, we demonstrate how to use normal Python threading
to speed up the same nonsense calculation I used in previous examples:

# cython: boundscheck=False, cdivision=True


import array
import threading

General-Purpose Libraries | 63
cpdef void target ( double [:] piece ) nogil :
cdef int i , n = piece . shape [ 0 ]
with nogil :
for i in range ( n ):
piece [ i ] = i % 3

cdef int n = int ( 1e8 )


cdef object a = array . array ( 'd' , [ 0.0 ]) * n

view = memoryview ( a )
piece_size = int ( n / 2 )

thread1 = threading . Thread (


target = target ,
args = ( view [: piece_size ],)
)

thread2 = threading . Thread (


target = target ,
args = ( view [ piece_size :],)
)

thread1 . start ()
thread2 . start ()

thread1 . join ()
thread2 . join ()

print ( a [: 5 ])

The threading module in the standard library.

Thread objects want a target function to execute, so we wrap our calculation


inside a function. We declare (with the nogil
keyword) that our function may want to release the GIL. The actual point where

the GIL is released. The rest of the func tion is identical to before. Exactly the

same as before. We create a memory view of the data inside the array. Cython

is optimized to work with these kinds of memory views efficiently. (Did you know

that memoryview() is a built-in Python func tion?)

64 | Chapter 1: Expanding Your Python Knowledge: Lesser-Known Libraries


Were going to split up our big data array into two parts. Create normal Python

threads: we must pass both the target function and the view section as the

argument for the function. Note how each thread gets a different part of the

view! Threads are started.

We wait for the threads to complete.

Ive also sneakily added a few small optimization options such as disabling bounds
checking and enabling the faster C division. Cython is very configurable in how it
generates C code behind the scenes and the documentation is well worth
investigating. As before, we must compile our program:

$ cythonize -b -i -a cythondemopll.pyx

Then we can test the impact of our changes:

$ time python -c "import cythondemopll"


array ( 'd' , [ 0.0, 1.0, 2.0, 0.0, 1.0 ])

real 0m0.593s
user 0m0.390s
sys 0m0.276s

The use of threading has given us around 30% improvement over the previous,
single-threaded version, and were about 50 times faster than the original Python
version in this example. For a longer- running program the speedup factor would be
even more significant because the startup time for the Python interpreter would
account for a smaller portion of the time cost.

Executables with Cython

One final trick with Cython is creating executables. So far weve been compiling
our Cython code for use as a native extension mod ule, which we then import to
run. However, Cython also makes it possible to create a native binary executable
directly. The key is to invoke cython directly with the -- embed option:

$ cython --embed cythondemopll.pyx

This produces a C source file that will compile to an executable rather than a
shared library.

General-Purpose Libraries | 65
The next step depends on your platform because you must invoke the C compiler
directly, but the main thing you need to provide is the path to the Python header file
and linking library. This is how it looks on my Mac:

$ gcc ` python3.5-config --cflags ` cythondemopll.c \


` python3.5-config --ldflags ` -o cythondemopll

Here Ive used a utility called python3.5-config that conveniently returns the path to
the header file and the Python library, but you could also provide the paths directly.
The compilation step using gcc produces a native binary executable that can be run
directly on the command line:

$ ./cythondemopll array ( 'd' , [ 0.0, 1.0, 2.0, 0.0, 1.0 ])

There is much more to learn about Cython, and Ive made a com prehensive video
series, Learning Cython ( OReilly) that covers all the details. Cythons online
documentation is also an excellent refer ence.

awesome-python

Finally, we have awesome-python . Its not a library, but rather a huge, curated list of
a high-quality Python libraries covering a large number of domains. If you have not
seen this list before, make sure to reserve some time before browsing because once
you begin, youll have a hard time tearing yourself away!

Conclusion
There is much more to discover than what youve seen in this report. One of the
best things about the Python world is its enormous repository of high-quality
libraries.

You have seen a few of the very special features of the standard library like the collections
module, contextlib, the concur rent.futures module, and the logging module. If you do
not yet use these heavily, I sincerely hope you try them out in your next project.

In addition to those standard library modules, we also covered sev eral excellent
libraries that are also available to you on the PyPI. Youve seen how:

66 | Chapter 1: Expanding Your Python Knowledge: Lesser-Known Libraries


flit makes it easy for you to create your own Python packages, and submit them
to the PyPI.

libraries like colorama and begins improve your command-line applications.

tools like pyqtgraph and pywebview can save you lots of time when creating
modern user interfaces, including hug, which can give your applications an easily
created web API.

system libraries like psutil and watchdog can give you a clean integration with the
host operating system.

temporal libraries like arrow and parsedatetime can simplify the tangled mess that
working with dates and times often becomes.

general-purpose libraries like boltons and Cython can further enrich the
already powerful facilities in the Python standard library.

Hopefully you will be able to use one or more of the great libraries in your next
project, and I wish you the best of luck!

Conclusion | 67
About the Author

Caleb Hattingh is passionate about coding and has been program ming for over 15
years, specializing in Python. He holds a masters degree in chemical engineering
and has consequently written a great deal of scientific software within chemical
engineering, from dynamic chemical reactor models all the way through to data
analy sis. He is very experienced with the Python scientific software stack, CRM,
financial software development in the hotels and hospitality industry, frontend web
experience using HTML, Sass, JavaScript (loves RactiveJS), and backend
experience with Django and web2py. Caleb is a regular speaker at PyCon Australia
and is actively engaged in the community as a CoderDojo Mentor, Software
Carpentry helper, Govhacker, Djangogirls helper, and even Railsgirls helper. Caleb
is the founder of Codermoji , and posts infrequent idle rants and half-baked ideas to
his blog at pythonomicon.com .

Você também pode gostar