Ambiente e Sintaxe

Autor

Douglas Braga

Nota

Esta seção corresponde a The Zen of Python, Getting Python, Virtual Environments, Whitespace Formatting e Modules, do capítulo 2 de Grus (2019).

DicaO que esta seção assume

Que você sabe o que é um interpretador, um módulo e uma dependência. O que provavelmente é novo: a disciplina de ambiente isolado e as formas de import que este livro usa.

O Zen do Python

Python tem uma descrição zen-budista dos seus princípios de projeto, que você lê digitando import this no interpretador. Um dos mais discutidos é:

Deve haver um — e preferencialmente apenas um — modo óbvio de fazer.

Código escrito nesse modo óbvio (que pode não ser óbvio de cara para quem chega de outra linguagem) costuma ser chamado de “Pythônico”. Este livro tenta escrever Python pythônico, e a palavra vai reaparecer nas próximas seções sempre que houver duas formas de fazer a mesma coisa e uma delas for a preferida.

Ambientes virtuais

Aqui vale desacelerar, porque é um hábito de engenharia que não depende de saber Python.

O problema: projetos diferentes precisam de versões diferentes das mesmas bibliotecas. Se você instalar tudo no Python do sistema, um projeto que precisa de uma versão nova quebra o outro que precisa da antiga — e você descobre isso no pior momento possível.

A solução é um ambiente virtual: uma instalação de Python isolada, por projeto, com as suas próprias bibliotecas.

ImportanteIsolar não basta: trave as versões

O ambiente isolado resolve o conflito entre projetos. Falta a outra metade: registrar num arquivo de lock quais versões o projeto usa, para que a mesma instalação possa ser reconstruída depois — na sua máquina daqui a um ano, ou na máquina de outra pessoa hoje.

O motivo é concreto. Uma atualização de biblioteca pode mudar em silêncio o comportamento de uma operação: já aconteceu com uma comparação do pandas, que passou a devolver a resposta errada sem erro e sem aviso. Sem as versões travadas, quando um resultado muda você não tem como saber se mudou porque o dado mudou, porque você mexeu no código, ou porque uma dependência foi atualizada embaixo de você.

Formatação por espaço em branco

Python usa indentação para delimitar blocos, onde outras linguagens usam chaves:

for i in [1, 2, 3, 4, 5]:
    for j in [1, 2, 3, 4, 5]:
        print(i + j, end=" ")   # a indentação diz o que está dentro de quê
    print("|", end=" ")
2 3 4 5 6 | 3 4 5 6 7 | 4 5 6 7 8 | 5 6 7 8 9 | 6 7 8 9 10 | 

Isso torna o código legível e cria uma classe de erro que outras linguagens não têm: a indentação errada muda o significado sem gerar erro de sintaxe. Um bloco recuado um nível a mais ou a menos ainda é código válido, com comportamento diferente.

O espaço em branco é ignorado dentro de parênteses e colchetes, o que permite quebrar expressões longas:

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

soma = (1 + 2 + 3 +
        4 + 5 + 6)

lista_longa, soma
([1, 2, 3, 4, 5, 6, 7, 8, 9], 21)

Você vai ver esse recurso o tempo todo no código do livro — as definições de função com muitos parâmetros são quebradas assim, um por linha.

Módulos e imports

Recursos que não são carregados por padrão precisam ser importados. A forma mais simples traz o módulo inteiro:

import re

meu_regex = re.compile("[0-9]+", re.I)
type(meu_regex).__name__
'Pattern'

Se você já tiver um re no seu código, pode dar um apelido:

import re as regex

regex.compile("[0-9]+") is not None
True

Apelidos também servem quando o nome do módulo é comprido ou quando existe uma convenção — import matplotlib.pyplot as plt é a que você mais vai encontrar neste livro.

E dá para importar valores específicos de um módulo, usando-os diretamente:

from collections import defaultdict, Counter

contador = Counter()
type(contador).__name__
'Counter'
AvisoUma quarta forma, que você não deve usar

Existe ainda uma forma que importa tudo para o espaço de nomes atual:

from re import *      # nunca faça isto

Ela sobrescreve silenciosamente qualquer nome que você já tivesse. O módulo re tem uma função chamada match; se você tinha uma variável match, ela desapareceu — e você vai descobrir isso muito depois, com um erro que não aponta para a causa.

Use import módulo ou from módulo import nome, listando sempre o que você traz.

Grus, Joel. 2019. Data Science from Scratch: First Principles with Python. 2nd ed. O’Reilly Media.