Escolar Documentos
Profissional Documentos
Cultura Documentos
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
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
800-998-9938 ou corporate@oreilly.com.
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
v
CAPTULO 1
Expandir o seu
conhecimento Python:
Bibliotecas menos conhecidos
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:
1 Procura classificadas tipos de contineres? a excelente recipientes ordenadas pacote tem alto desempenho verses
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:
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
A Biblioteca Padro | 3
Aqui est um exemplo comum:
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
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.
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:
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:
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:
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:
Esta uma boa sintaxe porque simplifica o Limpar passo, onde o identificador de arquivo
lembrar de fazer f.close () -se: isso vai acontecer automaticamente quando o com sadas de
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
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
determinada na prxima linha. Depois de produo, podemos escrever o cdigo que ser
arquivos, isso seria onde voc fech-las. Neste exemplo, este o lugar onde ns
A Biblioteca Padro | 7
Aqui ns tentamos a estratgia alternativa de criao de matriz: primeiro, criar a matriz e, em
Para se divertir, usaremos nosso, novo gerente de contexto incrvel para tambm medir o
tempo total.
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
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
importar enfiando
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
urls = "" "Google twitter facebook youtube pinterest Tumblr instagram reddit flickr colegas
meetup microsoft apple linkedin xing RenRen Disqus Snapchat twoo whatsapp" "" . Dividido ()
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
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
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:
Para isso:
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.
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:
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:" )
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
explorando com o registrador de raiz muito bem. Voc precisa chamar um configurao mtodo;
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:
ele ser executado com o conjunto de nvel de registo para DEBUG ( por isso todas as mensagens logger
ele ser executado no ATENO nvel para o registo, ento tudo INFO e DEPURAR
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
importar sched
importar Tempo
4 programas que automatizam alguma tarefa, muitas vezes, a comunicao de dados entre os diferentes servios de rede como o
A Biblioteca Padro | 13
impresso ( Tempo . ctime ())
Agendador . entrar ( 10 , prioridade = 0 , aao = saytime )
saytime ()
experimentar :
Note que reprogramar a funo dentro de si, com um segundo de atraso de dez.
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
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
reagendar ()
experimentar :
Crie um Agendador exemplo, como antes. Obter hora atual, mas retirar segundos e
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
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.
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:
Do pacote nisso arquivo um timo lugar para adicionar pacote de informa- o, como
documentao, nmeros de verso, e autor informa- o.
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
__version__ = '1.0.0'
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:
Note-se que voam registra automaticamente o seu pacote se o upload inicial falhar.
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 .
voar permite especificar mais opes, mas para pacotes simples que voc v aqui
pode chegar muito longe.
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.
mensagens = [
'bl bl bl' , ( dianteiro . LIGHTYELLOW_EX + Estilo . BRILHANTE
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
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
Obter um logger exemplo, exatamente como voc faria normalmente. Defina o nvel de log.
para ser o ColoredFormatter fornecida pelo colorlog biblioteca. Isto produz a sada
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!
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
Como seria de esperar, a ajuda pode ser obtido pela passagem - h para este pro- grama:
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
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.
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:
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 )
@ 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 ):
...
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. ''"
outro :
impresso ( ' Muito bem, obrigado.' )
@ begin.subcommand
def buscar ( url : 'Fonte de dados' = 'Http://google.com' ):
"" "Fetch dados do URL. ''"
impresso ( ' Trabalho vai aqui' )
O primeiro, status, representa um subcomando que poderia ser usado para fornecer algum
tipo de status do sistema mensagem (acho que tus esta- git).
$ python beginssubdemo.py uso -h: beginssubdemo.py [ -h ] [ --uma A ] [ --b B ] { buscar, estado } ...
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.
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.
Isto ir instalar e executar o navegador exemplos. Voc pode ver uma imagem de
um dos exemplos em Figura 1-4 .
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:
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
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
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
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!
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.
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 *
inicializao = 'Https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/'
bootswatch = 'Https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/'
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' )
@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 )
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
fornece uma interface muito simples para a construo de um aplicativo da web bsico
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
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
A execuo deste programa produz uma grande-olhando interface, como mostrado na Figura 1-6 .
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 .
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
importar psutil
Sada:
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.
importar psutil
importar OS , sys , Tempo
pid = OS . getpid ()
p = psutil . Processo ( pid )
impresso ( ' Informaes do processo:' )
dados = []
enquanto Verdade :
psutil constri um Processo() objeto com base no PID. Neste caso, o PID o nosso
Isso parece ruim: um loop infinito e uma lista cada vez maior! Sada:
informaes do processo :
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
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:
tarefas de convenincia, como formatadores que funcionam automaticamente, fiapos ERS e exames:
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:
PatternMatchingEventHandler , FileModifiedEvent ,
FileCreatedEvent )
observador = Observador ()
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
mentadas implementa para criao e modificao, mas existem vrios outros mtodos que
eventos, e dizer co de guarda o que deveria estar assistindo. Neste caso, eu pedi para as
mtodo, voc pode forar o fluxo do programa para bloquear neste momento. Com esse cdigo
$ tocar secrets.txt
$ tocar secrets.txt
$ tocar secrets.txt
[ etc ]
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
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,
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
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
@ 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 )
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
"vermelho"
"# 87cefa"
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:
"/ Nametohex" : {
"OBTER" : {
"outputs" : {
"formato" : "JSON (JavaScript Serialized
Object Notation)" ,
"tipo de contedo" : "Application / json"
},
"inputs" : {
"nome" : {
"tipo" : "Text valor bsico / string"
}}}}}}}
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.
recente do mesma API retorna o resultado como calculada pela flexionar, sem qualquer
alterao.
"Caminhada bobo"
"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):
"Parva Walk"
"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:
],
"manipuladores" : {
"/singular" : {
[ recorte... ]
seja, v2, retorna a documentao para que sion ver-. o docstring de cada funo
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.
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
a realidade de que sua aplicao vai freqentemente executados em uma regio tempo- diferente
novamente para onde os usurios esto localizados. o ingnuo data hora objetos so os que voc
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:
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
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:
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
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.
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 ()
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:
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'
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:
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" ,
]
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.
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 ()))
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.
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.
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 """
@cached ( cache_POS )
def part_of_speech ( word ):
items = vb . part_of_speech ( word . lower ())
if items :
return json . loads ( items )[ 0 ][ 'text' ]
@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' ])
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
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.
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.
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
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
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:
cardinalize: given a word and a count, change the word for plurality and preserve
case:
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
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 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
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 ])
data would come from another source such as an image for image-processing
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.
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 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:
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
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.
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.
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:
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
view = memoryview ( a )
piece_size = int ( n / 2 )
thread1 . start ()
thread2 . start ()
thread1 . join ()
thread2 . join ()
print ( a [: 5 ])
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
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
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
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.
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:
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:
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:
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:
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 .