Eu entendo que os arquivos ".pyc" são versões compiladas dos arquivos ".py" de texto simples, criados em tempo de execução para fazer os programas rodarem mais rápido. No entanto, observei algumas coisas:
- Após a modificação dos arquivos "py", o comportamento do programa muda. Isso indica que os arquivos "py" são compilados ou, pelo menos, passam por algum tipo de processo de hash ou comparam os registros de data e hora para saber se devem ou não ser recompilados.
- Ao excluir todos os arquivos ".pyc" (
rm *.pyc
), às vezes o comportamento do programa muda. O que indicaria que eles não estão sendo compilados na atualização de ".py" s.
Questões:
- Como eles decidem quando serão compilados?
- Existe uma maneira de garantir que eles tenham uma verificação mais rigorosa durante o desenvolvimento?
python
python-internals
pyc
Aaron Schif
fonte
fonte
rm *.pyc
. Isso não excluirá arquivos .pyc em pastas aninhadas. Use em seufind . -name '*.pyc' -delete
lugarRespostas:
Os
.pyc
arquivos são criados (e possivelmente sobrescritos) apenas quando o arquivo Python é importado por algum outro script. Se a importação for chamada, o Python verificará se o.pyc
carimbo de data / hora interno do arquivo não é mais antigo que o.py
arquivo correspondente . Se for, ele carrega o.pyc
; se não for ou se.pyc
ainda não existir, o Python compila o.py
arquivo em um.pyc
e o carrega.O que você quer dizer com "verificação mais rigorosa"?
fonte
rm *.pyc
. Eu sei que se eu forçar a recriação de todos os arquivos, alguns problemas serão corrigidos, indicando que os arquivos não estão sendo recompilados por si próprios. Suponho que, se eles usarem os carimbos de data / hora, não haverá como tornar esse comportamento mais rígido, mas o problema ainda persiste..pyc
carimbo de data / hora de deve ser anterior ao.py
carimbo de data / hora correspondente para acionar uma recompilação.Arquivos .pyc gerados sempre que os elementos de código correspondentes são importados e atualizados se os arquivos de código correspondentes foram atualizados. Se os arquivos .pyc forem excluídos, eles serão regenerados automaticamente. No entanto, eles não são excluídos automaticamente quando os arquivos de código correspondentes são excluídos.
Isso pode causar alguns erros realmente divertidos durante os refatores em nível de arquivo.
Em primeiro lugar, você pode acabar empurrando um código que só funciona na sua máquina e em mais ninguém. Se você tiver referências pendentes a arquivos excluídos, eles ainda funcionarão localmente se você não excluir manualmente os arquivos .pyc relevantes, porque os arquivos .pyc podem ser usados nas importações. Isso é agravado pelo fato de que um sistema de controle de versão configurado corretamente irá apenas enviar arquivos .py para o repositório central, não arquivos .pyc, o que significa que seu código pode passar no "teste de importação" (tudo importa bem) muito bem e não trabalhar no computador de outra pessoa.
Em segundo lugar, você pode ter alguns bugs terríveis se transformar pacotes em módulos. Quando você converte um pacote (uma pasta com um
__init__.py
arquivo) em um módulo (um arquivo .py), os arquivos .pyc que antes representavam esse pacote permanecem. Em particular, os__init__.pyc
restos mortais. Então, se você tiver o pacote foo com algum código que não importa, então exclua esse pacote e crie um arquivo foo.py com alguma funçãodef bar(): pass
e execute:você obtém:
porque o python ainda está usando os arquivos .pyc antigos do pacote foo, nenhum dos quais define bar. Isso pode ser especialmente problemático em um servidor da web, onde o código em pleno funcionamento pode quebrar por causa de arquivos .pyc.
Como resultado de ambos os motivos (e possivelmente outros), o código de implantação e o código de teste devem excluir arquivos .pyc, como a seguinte linha de bash:
Além disso, a partir do python 2.6, você pode executar o python com o
-B
sinalizador para não usar arquivos .pyc. Consulte Como evitar arquivos .pyc? para mais detalhes.Consulte também: Como removo todos os arquivos .pyc de um projeto?
fonte
__init__.py
arquivo) ...". Isso seria um pacote, não um módulo.__init__.pyc
restos mortais. - Por quê? Como um pacote é um diretório, deletar um pacote significa deletar diretório, portanto, não há arquivos restantes ....pyc
problema também é um motivo: dependências ocultas no sistema operacional e níveis de patch de utilitário,.so
arquivos , arquivos de configuração, outras bibliotecas Python (se você não estiver executando em um ambiente virtual), vars env obscuros ... a lista continua. Para ser completo e encontrar todos esses problemas, você precisa fazer uma cópia limpa do seu código em um repositório git ou publicar como um pacote em um servidor estilo PyPi e fazer uma clonagem completa ou configuração em uma nova VM. Alguns desses problemas potenciais tornam esse.pyc
problema insignificante em comparação.