Gerando Bytecode de Módulos em Python
Quando executamos um script em Python, geralmente o processo é dividido em duas etapas:
- O arquivo com o código (extensão
.py
) é compilado para um bytecode intermediário. - Em seguida, o bytecode compilado é interpretado, o que representa a execução propriamente dita do programa.
Não precisamos gerar bytecode explicitamente, pois ele é criado automaticamente durante a execução do script Python. Se o programa importa módulos ou bibliotecas externos e essa é a primeira importação, o bytecode compilado desses módulos é salvo em um arquivo com extensão .pyc
e armazenado no diretório __pycache__
, na mesma pasta onde o arquivo de código Python está localizado. Caso façamos modificações no código original de uma biblioteca, o Python recompila o bytecode. Se não houver alterações, o bytecode previamente compilado é carregado do arquivo .pyc
, o que otimiza a execução do programa, tornando a compilação e execução mais rápidas.
No entanto, o bytecode do script principal, ou seja, o arquivo principal do programa que é passado para o interpretador, não é salvo em um arquivo .pyc. Ele é recompilado toda vez que a aplicação é iniciada.
Suponha que temos um arquivo user.py
em nossa pasta de projeto, contendo uma função simples que recebe dois parâmetros e exibe seus valores:
def printUser(username, userage):
print(f"Name: {username} Age: {userage}")
Vamos agora importar esse arquivo no módulo principal do programa, que chamaremos de app.py
:
import user
username = "Tom"
userage = 39
user.printUser(username, userage)
Ao executar esse script na pasta do projeto (onde o módulo user.py
está localizado), será criado um diretório __pycache__
. Dentro desse diretório, será gerado um arquivo de bytecode chamado algo como user.cpython-311.pyc
, onde a versão (por exemplo, 311
) representa a versão do interpretador Python utilizado (Python 3.11
neste caso). Esse arquivo .pyc
é binário, portanto não há utilidade em abri-lo em um editor de texto.
. ├── __pycache__ │ └── user.cpython-311.pyc ├── app.py └── user.py
Compilando Bytecode Manualmente
Embora o bytecode seja gerado automaticamente, também é possível criá-lo manualmente. Existem várias formas de fazer isso: usando o script py_compile
ou o módulo compileall
.
Utilizando o py_compile
O script py_compile
é usado para compilar arquivos individuais. Para compilar o script user.py
em um arquivo de bytecode, podemos usar o seguinte código:
import py_compile
py_compile.compile("user.py") # caminho para o script
Passamos o caminho do script para a função compile()
. Após a execução, o diretório __pycache__
será criado na pasta atual, contendo o arquivo user.cpython-311.pyc
.
Utilizando o compileall
O módulo compileall
permite compilar todos os arquivos Python em um diretório específico. Por exemplo, para compilar todos os arquivos em C:/python/files
, usamos:
python -m compileall C:/python/files
Por padrão, até mesmo arquivos em subdiretórios serão compilados. Se quisermos compilar apenas os arquivos na pasta especificada, sem incluir subpastas, usamos a opção -l
:
python -m compileall -l C:/python/files
Documentação oficial