Diretórios __pycache__ e arquivos *.pyc

Publicado em 2017-03-13 por Vinicius Assef

Quem nunca ficou incomodado com os diretórios __pycache__ criados pelo Python? Ou com os arquivos .pyc criados pelo Python legado (Python 2)?

Eles poluem um pouco o ambiente, mas têm sua utilidade: desempenho.

Quando o Python executa seu programa pela primeira vez, ele gera um arquivo com extensão .pyc com o bytecode e salva-o no diretório __pycache__. Se na próxima vez que você requisitar o mesmo programa, ele não tiver modificado, o bytecode já está gerado e tudo fica mais rápido.

Sim, simplifiquei bastante, mas no final o resultado é esse. Para mais detalhes, leia a seção "Compiled" Python files da documentação oficial.

Então, os arquivos .pyc são úteis porque aceleram a importação dos módulos. Vale notar que não há diferença de desempenho entre uma versão compilada (extensão "pyc") e a versão fonte (extensão "py"). Somente o tempo de carga é menor quando já existe a versão compilada.

Enquanto esse funcionamento é fundamental em ambiente de produção, no seu ambiente de desenvolvimento eles atrapalham um pouco. Quando você vai rodar um find ou um grep, eles acabam vindo sempre no resultado. Uma solução é excluí-los toda vez que você for fazer uma busca no seu projeto.

Outra solução mais definitiva é abrir mão deles no ambiente de desenvolvimento. Existem 2 formas:

  1. Passar o parâmetro -B para o executável Python, assim: python -B meu_programa.py.

  2. Ajustar a variável de ambiente PYTHONDONTWRITEBYTECODE antes de executar o Python.

Ambas alternativas têm o mesmo efeito. Elas dizem ao Python para não gravar em disco a versão compilada dos módulos. A segunda alternativa me atende melhor e vou mostrar como usá-la.

Em Linux ou MacOS, basta executar o comando abaixo antes de chamar o Python:

$ export PYTHONDONTWRITEBYTECODE=1

De acordo com a documentação você pode atribuir qualquer conteúdo à variável PYTHONDONTWRITEBYTECODE para ativá-la.

Se você quer realmente livrar-se dos arquivos compilados de uma vez por todas, inclua esse comando no seu arquivo ~/.bashrc ou ~/.profile e pronto.

Mas, dependendo da situação, manter os arquivos compilados podem ajudar. Por exemplo, se você pratica TDD eles vão acelerar a execução dos testes. Nesse caso, prefira manter os arquivos compilados e apagá-los com o find quando for conveniente:

$ find . -type d -name '__pycache__' -prune -exec rm -rf {} \;

Se você usa Python legado, o comando é:

$ find . -name '*.pyc' -exec rm {} \;

A título de curiosidade, vale a pena ler a documentação sobre as variáveis de ambiente usadas pelo Python. Algumas delas podem lhe ser úteis em outras ocasiões.

Update: o Eduardo Klosowski me contactou e acrescentou um comando que eu não conhecia para apagar os arquivos *.pyc, o pyclean. As distribuições Debian e derivadas (Ubuntu e Mint incluídas) trazem esse comando, mas no MacOS não tem. Nem o pyenv, que eu uso, também não tem. Para mais informações, acesse a manpage do pyclean.

Vinicius Assef

Eu sou apaixonado por Python e shell script.

Aprenda com seus erros e dê nome certo às coisas.