Python venv
Na aula pip: Instalando Pacotes, o Ubuntu recusou o pip install e sugeriu "crie um ambiente virtual". Lá você usou três comandos sem muita explicação. Nesta aula você vai entender o que é esse ambiente virtual (em inglês, virtual environment, abreviado venv), o que tem dentro dele, como ligar e desligar, e por que todo projeto Python sério tem o seu.
- O que é um ambiente virtual e por que cada projeto tem o seu.
- A criar um com
python3 -m venv .venve a ver o que tem dentro da pasta. - A ativar (
source .venv/bin/activate), reconhecer o prompt(.venv)e desativar (deactivate). - A conferir qual Python está em uso:
which pythonesys.prefix. - A apagar e recriar o ambiente a partir do
requirements.txt. - Os erros reais: ativar sem
source, pasta errada, copiar o projeto com a.venvjunto.
Ambientes virtuais são criados e ativados no terminal do seu computador. As janelas de terminal mostram o que o Ubuntu 26.04 da Ana respondeu de verdade. O editor do guia (o "Experimente") roda o Python do navegador, que não tem ambientes virtuais; as caixas desta aula treinam a lógica com os arquivos do ambiente.
A ideia: uma caixa de ferramentas para cada trabalho
A Ana faz bolos para fora e também conserta bicicletas no fim de semana. Ela não guarda as formas de bolo junto com as chaves de boca: cada atividade tem a sua caixa, com as ferramentas certas. Se um dia ela trocar a batedeira, a caixa da bicicleta nem fica sabendo.
Com os programas Python é igual. A lojinha da Ana usa o requests na versão mais nova; a agenda, que ela escreveu no ano passado, só funciona com uma versão mais antiga. Se os dois projetos usassem o mesmo Python, com os mesmos pacotes, um deles ia quebrar. A solução é dar a cada projeto a sua caixa:
| Sem ambiente virtual | Com um ambiente virtual por projeto |
|---|---|
| Todos os programas dividem os mesmos pacotes | Cada projeto tem os pacotes dele, numa pasta dele |
| Uma versão de cada pacote no computador inteiro | A lojinha com o requests 2.34.2, a agenda com o 2.32.3, ao mesmo tempo |
No Ubuntu, o pip install nem funciona (PEP 668) | O pip funciona, sem sudo |
| Difícil saber do que o projeto precisa | O pip freeze do ambiente é a lista exata |
Um ambiente virtual é só isso: uma pasta com um Python "particular" e um lugar para os pacotes daquele projeto. Nada é instalado no sistema, e apagar a pasta desfaz tudo.
1. Criando: python3 -m venv .venv
A Ana vai começar um projeto novo, as encomendas da padaria. Primeiro a pasta do projeto, depois o ambiente dentro dela:
$ mkdir padaria $ cd padaria $ python3 -m venv .venv $ ls -a . .. .venv
- python3
- O Python que vai servir de base para o ambiente (o do sistema, o 3.14).
- -m venv
- "Rode o módulo
venv": ele vem com o Python e sabe criar ambientes. - .venv
- O nome da pasta do ambiente. Pode ser qualquer nome, mas
.venvé o costume: os editores de código (como o VS Code) procuram por ele, e o ponto na frente deixa a pasta "escondida" nolscomum (por isso o-a, de "all", "todos").
O comando não imprime nada: no terminal, silêncio quer dizer que deu certo. Leva um ou dois segundos, porque ele também instala um pip novinho lá dentro.
O que tem dentro da .venv
$ ls -a .venv . .. .gitignore bin include lib lib64 pyvenv.cfg
| Item | O que é |
|---|---|
bin/ | Os programas do ambiente: python, pip e o script activate (de "binários") |
lib/python3.14/site-packages/ | Onde o pip do ambiente instala os pacotes |
include/, lib64 | Detalhes internos; você não mexe neles |
pyvenv.cfg | A "ficha" do ambiente: de qual Python ele saiu |
.gitignore | Um aviso para o git ignorar a pasta inteira (o ambiente não vai para o repositório) |
$ cat .venv/pyvenv.cfg home = /usr/bin include-system-site-packages = false version = 3.14.4 executable = /usr/bin/python3.14 command = /usr/bin/python3 -m venv /home/ana/padaria/.venv $ cat .venv/.gitignore # Created by venv; see https://docs.python.org/3/library/venv.html *
- home = /usr/bin
- A pasta do Python original.
- include-system-site-packages = false
- "Incluir os pacotes do sistema? Não." O ambiente começa limpo e não enxerga os pacotes instalados pelo
apt. - version = 3.14.4
- A versão do Python do ambiente.
- command = …
- O comando que criou o ambiente, com o caminho completo da pasta. Guarde isso: o ambiente sabe onde foi criado.
- *
- No
.gitignore, o asterisco quer dizer "ignore tudo nesta pasta".
E a pasta bin:
$ ls -l .venv/bin total 36 -rw-r--r-- 1 ana ana 9031 Oct 18 11:48 Activate.ps1 -rw-r--r-- 1 ana ana 2158 Oct 18 11:48 activate -rw-r--r-- 1 ana ana 914 Oct 18 11:48 activate.csh -rw-r--r-- 1 ana ana 2185 Oct 18 11:48 activate.fish -rwxrwxr-x 1 ana ana 240 Oct 18 11:48 pip -rwxrwxr-x 1 ana ana 240 Oct 18 11:48 pip3 -rwxrwxr-x 1 ana ana 240 Oct 18 11:48 pip3.14 lrwxrwxrwx 1 ana ana 7 Oct 18 11:48 python -> python3 lrwxrwxrwx 1 ana ana 16 Oct 18 11:48 python3 -> /usr/bin/python3 lrwxrwxrwx 1 ana ana 7 Oct 18 11:48 python3.14 -> python3 lrwxrwxrwx 1 ana ana 7 Oct 18 11:48 𝜋thon -> python3
- activate
- O script que liga o ambiente no bash (o terminal do Ubuntu). Os outros (
.csh,.fish,.ps1) são para outros terminais, como o PowerShell do Windows. - pip, pip3, pip3.14
- Três nomes para o mesmo
pip, o do ambiente. - python3 -> /usr/bin/python3
- A seta indica um atalho (link simbólico): o Python do ambiente não é uma cópia inteira, é um atalho para o Python do sistema. O que muda é onde ele procura os pacotes.
- python -> python3
- Dentro do ambiente existe o comando
python, sem o 3. Fora dele, no Ubuntu, não existe. - 𝜋thon
- Uma brincadeira do Python 3.14 (o "pi" de 3,14…): mais um atalho, com a letra grega π. Funciona, mas ninguém usa no dia a dia.
2. Ativando: source .venv/bin/activate
Criar o ambiente não basta: o terminal continua usando o Python do sistema. Veja:
$ which python3 /usr/bin/python3 $ python3 -c "import sys; print(sys.prefix)" /usr
which ("qual") mostra qual programa roda quando você digita um nome. E sys.prefix é a pasta "de casa" do Python que está rodando (o módulo sys tem aula própria: Os Módulos os e sys). Os dois apontam para o sistema. Agora a Ana ativa o ambiente:
$ source .venv/bin/activate (.venv) ana@notebook:~/padaria$ which python3 /home/ana/padaria/.venv/bin/python3 (.venv) ana@notebook:~/padaria$ which python /home/ana/padaria/.venv/bin/python (.venv) ana@notebook:~/padaria$ python -c "import sys; print(sys.prefix)" /home/ana/padaria/.venv (.venv) ana@notebook:~/padaria$ pip list Package Version ------- ------- pip 25.1.1
- source
- "Leia e execute este arquivo aqui, neste terminal". É obrigatório: o
activatemuda o terminal em que você está, e só osourcedeixa ele fazer isso. - .venv/bin/activate
- O caminho do script, a partir da pasta do projeto.
- (.venv)
- O prompt ganhou o nome do ambiente na frente. É o sinal de que ele está ativo: olhe para ele sempre antes de rodar
pip install. - which python3
- Agora aponta para dentro da
.venv. - pip list
- Só o
pip: o ambiente é novo e limpo.
O que o activate fez, por baixo, foi pôr a pasta .venv/bin na frente da lista de lugares onde o terminal procura os programas. Por isso python e pip agora são os do ambiente. Ele também criou a variável VIRTUAL_ENV, com o caminho do ambiente ativo (echo $VIRTUAL_ENV mostra).
O ambiente fica ativo na janela (ou aba) de terminal em que você rodou o source, até você desativar ou fechar a janela. Abriu outro terminal? Ele começa com o ambiente desligado, e você ativa de novo. É normal rodar o source .venv/bin/activate toda vez que senta para trabalhar no projeto.
A criação é igual (python -m venv .venv), mas a pasta se chama Scripts em vez de bin, e a ativação, no PowerShell, é .venv\Scripts\Activate.ps1. O resto da aula vale igual.
3. O próprio programa sabe se está num ambiente
Um programa Python consegue descobrir qual Python o está rodando. sys.executable é o caminho do Python em uso; sys.base_prefix é a pasta do Python original. Num ambiente virtual, sys.prefix (a pasta do ambiente) é diferente de sys.base_prefix:
import sys
print("Python em uso:", sys.executable)
print("Ambiente virtual?", sys.prefix != sys.base_prefix)
$ python3 onde.py Python em uso: /usr/bin/python3 Ambiente virtual? False $ source .venv/bin/activate (.venv) ana@notebook:~/padaria$ python onde.py Python em uso: /home/ana/padaria/.venv/bin/python Ambiente virtual? True
O mesmo arquivo, dois resultados: o que muda é qual Python roda o programa.
Usar o ambiente sem ativar
Ativar é uma comodidade. Dá para chamar o Python do ambiente direto, pelo caminho, sem source nenhum. O resultado é o mesmo:
$ .venv/bin/python onde.py Python em uso: /home/ana/padaria/.venv/bin/python Ambiente virtual? True
É assim que se roda um programa de um projeto a partir de outro script ou de um agendador, onde ninguém vai digitar source. O mesmo vale para o pip: .venv/bin/pip install requests instala no ambiente, ativo ou não. E por que o .venv/bin/pip sabe para qual Python instalar? Porque a primeira linha dele diz:
$ cat .venv/bin/pip
#!/home/ana/padaria/.venv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
O pip é um programinha Python, e a linha #! do começo (o "shebang") diz qual Python roda ele: o da .venv da padaria, com o caminho completo. Isso vai ser importante no Quando dá errado.
Missão: o pyvenv.cfg tem uma linha chave = valor por configuração. O programa já lê o arquivo; faça ele mostrar Este ambiente usa o Python 3.14.4, pegando o número da linha que começa com version. Dica: linha.split(" = ") separa a chave do valor.
with open("pyvenv.cfg", encoding="utf-8") as arquivo:
for linha in arquivo:
linha = linha.strip()
print(linha)
home = /usr/bin include-system-site-packages = false version = 3.14.4 executable = /usr/bin/python3.14 command = /usr/bin/python3 -m venv /home/ana/padaria/.venv
with open("pyvenv.cfg", encoding="utf-8") as arquivo:
for linha in arquivo:
linha = linha.strip()
chave, valor = linha.split(" = ")
if chave == "version":
print(f"Este ambiente usa o Python {valor}")
4. Desativando: deactivate
Terminou o trabalho no projeto? deactivate ("desativar") devolve o terminal ao normal. O (.venv) some do prompt, e o python sem 3 volta a não existir:
$ source .venv/bin/activate (.venv) ana@notebook:~/padaria$ deactivate $ which python $ python --version Comando 'python' não encontrado, você quis dizer: comando 'python3' do deb python3 comando 'python' do deb python-is-python3
O which python não respondeu nada: não há programa com esse nome fora do ambiente. Desativar não apaga nada; o ambiente continua lá, com os pacotes, esperando o próximo source.
5. Cada projeto com o seu
Agora o exemplo da introdução, de verdade. A agenda da Ana precisa do requests 2.32.3. Ela cria o ambiente da agenda com a opção --prompt, que troca o nome que aparece no prompt:
$ mkdir agenda $ cd agenda $ python3 -m venv .venv --prompt agenda $ source .venv/bin/activate (agenda) ana@notebook:~/agenda$ pip install -q "requests==2.32.3" (agenda) ana@notebook:~/agenda$ pip list Package Version ------------------ --------- certifi 2026.7.22 charset-normalizer 3.5.2 idna 3.20 pip 25.1.1 requests 2.32.3 urllib3 2.8.0 (agenda) ana@notebook:~/agenda$ deactivate
(O -q, de quiet, "quieto", faz o pip instalar sem imprimir o andamento.) E a lojinha, da aula do pip, continua com a versão dela:
$ cd ../loja $ source .venv/bin/activate (.venv) ana@notebook:~/loja$ pip list Package Version ------------------ --------- certifi 2026.7.22 charset-normalizer 3.5.2 idna 3.20 pip 25.1.1 requests 2.34.2 urllib3 2.8.0 (.venv) ana@notebook:~/loja$ deactivate
Duas versões do mesmo pacote no mesmo computador, cada uma na sua caixa, sem uma atrapalhar a outra.
--prompt ou não?
Com várias janelas de terminal abertas, (agenda) diz mais do que (.venv). Mas é só o rótulo: a pasta continua se chamando .venv, e o resto funciona igual.
6. Apagar e recriar: o ambiente é descartável
Um ambiente virtual não guarda nada que você escreveu: o seu código fica fora dele, na pasta do projeto. Por isso ele é descartável. Estragou, ficou com pacotes demais, mudou de versão do Python? Apague e crie de novo. O requirements.txt (aula pip) traz os pacotes de volta:
$ cd loja $ ls baixar.py requirements.txt $ rm -rf .venv $ python3 -m venv .venv $ source .venv/bin/activate (.venv) ana@notebook:~/loja$ pip install -q -r requirements.txt (.venv) ana@notebook:~/loja$ pip list Package Version ------------------ --------- certifi 2026.7.22 charset-normalizer 3.5.2 idna 3.20 pip 25.1.1 requests 2.34.2 urllib3 2.8.0 (.venv) ana@notebook:~/loja$ echo $VIRTUAL_ENV /home/ana/loja/.venv (.venv) ana@notebook:~/loja$ python baixar.py Código: 200 Tipo: text/html; charset=utf-8 Tamanho: 577 caracteres
(O ls não mostra a .venv porque o nome começa com ponto.) Os mesmos pacotes, nas mesmas versões, e o programa funcionando. Essa é a rotina de quem recebe um projeto Python de outra pessoa: criar o ambiente, ativar, pip install -r requirements.txt.
rm -rf não tem volta
O rm -rf .venv apaga a pasta e tudo dentro, sem perguntar e sem lixeira. Confira o nome antes de apertar Enter: um espaço a mais (rm -rf . venv) apagaria a pasta atual inteira.
Formas diferentes de usar o ambiente
| Jeito | Exemplo | Quando usar |
|---|---|---|
| Ativar e usar os nomes curtos | source .venv/bin/activate e depois python, pip | No dia a dia, trabalhando no projeto pelo terminal |
| Chamar pelo caminho, sem ativar | .venv/bin/python programa.py | Em scripts e agendadores, ou para um comando só |
python -m pip no ambiente | .venv/bin/python -m pip install requests | Quando você quer ter certeza de qual Python recebe o pacote |
| Deixar o editor de código cuidar | O VS Code (e outros) acha a .venv e ativa sozinho no terminal dele | Quando você programa num editor desses |
Quando dá errado
activate sem o source
$ .venv/bin/activate bash: .venv/bin/activate: Permissão negada
Parece lógico chamar o script pelo caminho, como um programa. Mas o activate não tem permissão de execução, de propósito (repare no -rw-r--r-- dele no ls -l: nenhum x). Se ele rodasse como programa, mudaria um terminal "filho" que fecha logo em seguida, e o seu terminal continuaria igual. Como consertar: source .venv/bin/activate (ou a forma curta, . .venv/bin/activate, com um ponto e um espaço).
$ source venv/bin/activate bash: venv/bin/activate: Arquivo ou diretório inexistente
A pasta se chama .venv, com ponto, e o comando pediu venv, sem. Muitos tutoriais usam venv ou env; o caminho tem de ser o da pasta que você criou. O mesmo erro aparece se você estiver em outra pasta: o caminho .venv/bin/activate é a partir de onde o terminal está. Como consertar: entre na pasta do projeto (cd ~/padaria) e confira o nome com ls -a.
deactivate sem ambiente ativo
$ deactivate deactivate: comando não encontrado
O deactivate só existe enquanto um ambiente está ativo: é o próprio activate que o cria. Sem (…) no prompt, não há o que desativar. Não é problema nenhum.
$ python3 -m venv
usage: python3 -m venv [-h] [--system-site-packages] [--symlinks | --copies]
[--clear] [--upgrade] [--without-pip] [--prompt PROMPT]
[--upgrade-deps] [--without-scm-ignore-files]
ENV_DIR [ENV_DIR ...]
python3 -m venv: error: the following arguments are required: ENV_DIR
"Os seguintes argumentos são obrigatórios: ENV_DIR" (environment directory, "pasta do ambiente"). A primeira parte é o resumo de uso: entre colchetes ficam as opções que você pode dar; ENV_DIR, sem colchetes, é o que você tem de dar. (Mensagens desse formato vêm do módulo argparse, que você vai usar para fazer os seus próprios programas de terminal na aula argparse.) Como consertar: python3 -m venv .venv.
.venv junto
A Ana quis fazer uma versão de teste da lojinha e copiou a pasta inteira. Ativou o ambiente da cópia e…
$ cp -r loja loja-copia $ cd loja-copia $ source .venv/bin/activate (.venv) ana@notebook:~/loja-copia$ which python /home/ana/loja/.venv/bin/python (.venv) ana@notebook:~/loja-copia$ pip --version pip 25.1.1 from /home/ana/loja/.venv/lib/python3.14/site-packages/pip (python 3.14)
Sem erro nenhum, mas olhe os caminhos: /home/ana/loja/.venv, e não loja-copia. O ambiente ativado foi o da pasta original. Um pip install agora mudaria a lojinha de verdade, e não a cópia de teste. O motivo: o ambiente guarda o caminho completo de onde foi criado (você viu no pyvenv.cfg e na primeira linha do pip), e o activate também:
$ grep -n "export VIRTUAL_ENV=" .venv/bin/activate 49: export VIRTUAL_ENV=/home/ana/loja/.venv
Um ambiente virtual não se muda de lugar: nem copiando, nem renomeando a pasta do projeto. Como consertar: na cópia, apague a .venv copiada e crie outra (rm -rf .venv, python3 -m venv .venv, pip install -r requirements.txt). E, para mandar o projeto para alguém, mande o código e o requirements.txt, nunca a .venv.
The virtual environment was not created successfully because ensurepip is not available
Em alguns Ubuntu e Debian, o python3 -m venv falha com essa mensagem (ilustrativa: no computador da Ana o pacote já está instalado). O Ubuntu separa a criação de ambientes num pacote próprio. Como consertar: sudo apt install python3-venv e crie o ambiente de novo (apague antes a pasta que ficou pela metade).
Para fechar, uma comparação que o próprio pip não faz por você: o que muda entre os ambientes de dois projetos.
Missão: os dicionários têm o pip freeze da lojinha e da agenda (pacote → versão). Complete o laço para mostrar, só dos pacotes com versões diferentes, uma linha como requests: loja 2.34.2, agenda 2.32.3.
loja = {"certifi": "2026.7.22", "idna": "3.20", "requests": "2.34.2", "urllib3": "2.8.0"}
agenda = {"certifi": "2026.7.22", "idna": "3.20", "requests": "2.32.3", "urllib3": "2.8.0"}
for pacote in loja:
print(pacote)
loja = {"certifi": "2026.7.22", "idna": "3.20", "requests": "2.34.2", "urllib3": "2.8.0"}
agenda = {"certifi": "2026.7.22", "idna": "3.20", "requests": "2.32.3", "urllib3": "2.8.0"}
for pacote in loja:
if loja[pacote] != agenda[pacote]:
print(f"{pacote}: loja {loja[pacote]}, agenda {agenda[pacote]}")
Referência rápida
| Comando | O que faz |
|---|---|
python3 -m venv .venv | Cria o ambiente na pasta .venv |
python3 -m venv .venv --prompt nome | Cria com outro rótulo no prompt: (nome) |
source .venv/bin/activate | Ativa o ambiente neste terminal (no Windows: .venv\Scripts\Activate.ps1) |
deactivate | Desativa |
which python | Mostra qual Python roda com esse nome |
echo $VIRTUAL_ENV | Mostra o caminho do ambiente ativo |
.venv/bin/python programa.py | Roda com o Python do ambiente, sem ativar |
rm -rf .venv | Apaga o ambiente (o código do projeto fica) |
pip install -r requirements.txt | Recoloca os pacotes num ambiente novo |
| Em Python | O que é |
|---|---|
sys.executable | O caminho do Python que está rodando o programa |
sys.prefix | A pasta do ambiente em uso (ou do Python do sistema) |
sys.base_prefix | A pasta do Python original |
sys.prefix != sys.base_prefix | True dentro de um ambiente virtual |
| Sintoma | Causa provável |
|---|---|
bash: .venv/bin/activate: Permissão negada | Faltou o source na frente |
bash: venv/bin/activate: Arquivo ou diretório inexistente | Nome da pasta errado ou terminal em outra pasta |
deactivate: comando não encontrado | Nenhum ambiente ativo |
error: the following arguments are required: ENV_DIR | Faltou o nome da pasta no python3 -m venv |
which python aponta para outra pasta | A .venv foi copiada ou movida: recrie |
ModuleNotFoundError de um pacote que você instalou | O ambiente não está ativo (sem (.venv) no prompt) |
Exercícios
1. Criar
Complete o comando que cria um ambiente virtual na pasta .venv:
2. Ativar
Complete o comando que ativa o ambiente no terminal:
3. Desativar
Qual comando desliga o ambiente ativo?
4. Como você sabe, olhando o terminal, que um ambiente virtual está ativo?
5. Por que cada projeto deve ter o seu ambiente virtual?
6. A Ana vai mandar a lojinha para a Bia. O que ela deve mandar?
Missão final: o ambiente está ativo?
Missão: o activate põe o nome do ambiente na frente do prompt. Complete a função prompt para devolver (.venv) ana@notebook:~/loja$ quando ambiente tiver um nome e só ana@notebook:~/agenda$ quando ambiente for None (aula O Valor None).
def prompt(pasta, ambiente):
base = f"ana@notebook:{pasta}$"
return base
print("Com ambiente:", prompt("~/loja", ".venv"))
print("Sem ambiente:", prompt("~/agenda", None))
def prompt(pasta, ambiente):
base = f"ana@notebook:{pasta}$"
if ambiente is None:
return base
return f"({ambiente}) {base}"
print("Com ambiente:", prompt("~/loja", ".venv"))
print("Sem ambiente:", prompt("~/agenda", None))
Resumo
- Um ambiente virtual é uma pasta (o costume é
.venv) com um Python particular e os pacotes de um projeto. - Crie com
python3 -m venv .venv, ative comsource .venv/bin/activate, desative comdeactivate. - Ativo, o prompt começa com
(.venv), epythonepipsão os do ambiente (which pythonconfirma). Vale só para aquele terminal. - Sem ativar, chame pelo caminho:
.venv/bin/python programa.py. - Cada projeto com o seu: dois projetos podem usar versões diferentes do mesmo pacote no mesmo computador.
- O ambiente é descartável e preso ao lugar onde foi criado: não copie nem mova; apague e recrie com
pip install -r requirements.txt.