Você já pensou em como as bibliotecas de ambiente virtual funcionam no Python? Neste artigo, proponho me familiarizar com o conceito principal usado por todas as bibliotecas de ambientes, como virtualenv, virtualenvwrapper, conda, pipenv.
Inicialmente, no Python não havia capacidade interna de criar ambientes, e esse recurso foi implementado como um hack. Como se viu, todas as bibliotecas são baseadas em um recurso muito simples do interpretador python.
Quando o Python inicia o intérprete, ele começa a procurar o diretório com os módulos (site-packages). A pesquisa começa com o diretório pai em relação à localização física do executável do intérprete (python.exe). Se a pasta do módulo não for encontrada, o Python aumentará um nível e o fará até o diretório raiz ser atingido. Para entender que esse é um diretório com módulos, o Python procura o módulo os, que deve estar no arquivo os.py e é necessário para o python funcionar.
Vamos imaginar que nosso intérprete esteja localizado em
/usr/dev/lang/bin/python
. Em seguida, os caminhos de pesquisa terão a seguinte aparência:
/usr/dev/lang/lib/python3.7/os.py /usr/dev/lib/python3.7/os.py /usr/lib/python3.7/os.py /lib/python3.7/os.py
Como você pode ver, o Python adiciona um prefixo especial (
lib/python$VERSION/os.py
) ao nosso caminho. Assim que o intérprete encontra a primeira correspondência (a presença do arquivo os.py), ele altera
sys.prefix
e
sys.exec_prefix
para esse caminho (com o prefixo removido). Se, por algum motivo, nenhuma correspondência for encontrada, o caminho padrão será usado, compilado no intérprete.
Agora vamos ver como uma das bibliotecas mais antigas e famosas, virtualenv, faz isso.
user@arb:/usr/home/test
Após a execução, ele cria diretórios adicionais:
user@arb:/usr/home/test/ENV
Como você pode ver, o ambiente virtual foi criado copiando o binário Python para uma pasta local (ENV / bin / python). Também podemos notar que a pasta pai contém
links simbólicos para os arquivos da biblioteca padrão do python. Não podemos criar um link simbólico para o arquivo executável, pois o intérprete ainda o renomeará para o caminho real.
Agora vamos ativar nosso ambiente:
user@arb:/usr/home/test
Este comando altera a variável de ambiente $ PATH para que o comando
python
aponte para nossa versão local do python. Isso é conseguido substituindo o caminho local da pasta bin no início da linha $ PATH, para que o caminho local tenha precedência sobre todos os caminhos à direita.
export "/usr/home/test/ENV/bin:$PATH" echo $PATH
Se você executar o script nesse ambiente, ele será executado usando o binário em
/usr/home/test/ENV/bin/python
. O intérprete usará esse caminho como ponto de partida para encontrar módulos. No nosso caso, os módulos da biblioteca padrão serão encontrados no caminho
/usr/home/test/ENV/lib/python3.7/
.
Este é o principal truque, graças ao qual todas as bibliotecas para trabalhar com ambientes virtuais funcionam.
Melhorias no Python 3
A partir da versão Python 3.3, um novo padrão apareceu, chamado
PEP 405 , que introduz um novo mecanismo para ambientes leves.
Este PEP adiciona uma etapa extra ao processo de busca. Se você criar o
pyenv.cfg
configuração
pyenv.cfg
, em vez de copiar o binário Python e todos os seus módulos, poderá simplesmente indicar sua localização nesta configuração.
Esse recurso é usado ativamente pelo módulo
venv padrão, que apareceu no Python 3.
user@arb:/usr/home/test2
user@arb:/usr/home/test2
Graças a esta configuração, em vez de copiar o binário, o venv simplesmente cria um link para ele. Se o parâmetro
include-system-site-packages
alterado para
true
, todos os módulos da biblioteca padrão serão automaticamente acessíveis no ambiente virtual.
Apesar dessas mudanças, a maioria das bibliotecas de terceiros para trabalhar com ambientes virtuais usa a abordagem antiga.
PS: Eu sou o autor deste artigo, você pode fazer qualquer pergunta.