Fui dado a entender que Python é uma linguagem interpretada ...
No entanto, quando olho para o meu código-fonte Python, vejo .pyc
arquivos que o Windows identifica como "Arquivos Python compilados".
De onde eles vêm?
java
e javac
.
Fui dado a entender que Python é uma linguagem interpretada ...
No entanto, quando olho para o meu código-fonte Python, vejo .pyc
arquivos que o Windows identifica como "Arquivos Python compilados".
De onde eles vêm?
java
e javac
.
Respostas:
Eles contêm código de bytes , que é o que o interpretador Python compila a fonte. Esse código é então executado pela máquina virtual do Python.
A documentação do Python explica a definição assim:
Python é uma linguagem interpretada, em oposição a uma linguagem compilada, embora a distinção possa ser imprecisa devido à presença do compilador de bytecodes. Isso significa que os arquivos de origem podem ser executados diretamente sem criar explicitamente um executável que é executado.
Fui dado a entender que Python é uma linguagem interpretada ...
Esse meme popular está incorreto, ou melhor, construído sobre um mal-entendido dos níveis (naturais) da linguagem: um erro semelhante seria dizer "a Bíblia é um livro de capa dura". Deixe-me explicar esse símile ...
"A Bíblia" é "um livro" no sentido de ser uma classe de (objetos físicos reais identificados como) livros; os livros identificados como "cópias da Bíblia" devem ter algo fundamental em comum (o conteúdo, embora até esses possam estar em idiomas diferentes, com traduções aceitáveis diferentes, níveis de notas de rodapé e outras anotações) - no entanto, esses livros são perfeitamente bem permitido diferir em uma infinidade de aspectos que não são considerados fundamentais - tipo de encadernação, cor da encadernação, fontes usadas na impressão, ilustrações, se houver, amplas margens graváveis ou não, números e tipos de marcadores embutidos , e assim por diante.
É bem possível que uma impressão típica da Bíblia esteja realmente encadernada - afinal, é um livro que costuma ser lido várias vezes, marcado em vários lugares, folheado em busca de indicadores de capítulo e verso , etc, etc, e uma boa ligação de capa dura pode fazer com que uma determinada cópia dure mais tempo sob esse uso. No entanto, essas são questões mundanas (práticas) que não podem ser usadas para determinar se um determinado objeto real do livro é uma cópia da Bíblia ou não: impressões em brochura são perfeitamente possíveis!
Da mesma forma, Python é "uma linguagem" no sentido de definir uma classe de implementações de linguagem que devem ser semelhantes em alguns aspectos fundamentais (sintaxe, a maioria das semânticas, exceto aquelas partes daquelas em que é explicitamente permitido diferir), mas são totalmente permitidas. diferir em quase todos os detalhes da "implementação" - incluindo como eles lidam com os arquivos de origem fornecidos, se eles compilam os fontes para alguns formulários de nível inferior (e, se houver, qual formulário - e se eles salvam esses formulários compilados, em disco ou em outro local), como eles executam os referidos formulários e assim por diante.
A implementação clássica, CPython, geralmente é chamada apenas de "Python", mas é apenas uma das várias implementações de qualidade de produção, lado a lado com o IronPython da Microsoft (que compila códigos CLR, como ".NET"), Jython (que é compilado com códigos da JVM), PyPy (que é escrito no próprio Python e pode ser compilado em uma enorme variedade de formulários de "back-end", incluindo a linguagem de máquina gerada "just-in-time"). Eles são todos Python (== "implementações da linguagem Python"), assim como muitos objetos de livro superficialmente diferentes podem ser Bíblias (== "cópias da Bíblia").
Se você estiver interessado no CPython especificamente: ele compila os arquivos de origem em um formulário de nível inferior específico do Python (conhecido como "bytecode"), o faz automaticamente quando necessário (quando não há um arquivo de bytecode correspondente a um arquivo de origem ou o arquivo bytecode é mais antigo que o código-fonte ou compilado por uma versão diferente do Python) geralmente salva os arquivos de bytecode em disco (para evitar recompilá-los no futuro). O OTOH IronPython normalmente compila os códigos CLR (salvando-os em disco ou não, dependendo) e os códigos Jython para JVM (salvando-os em disco ou não - ele usará a .class
extensão se os salvar).
Esses formulários de nível inferior são executados por "máquinas virtuais" apropriadas, também conhecidas como "intérpretes" - a VM CPython, o tempo de execução .Net, a Java VM (também conhecida como JVM), conforme apropriado.
Portanto, nesse sentido (o que as implementações típicas fazem), o Python é uma "linguagem interpretada" se, e somente se, C # e Java: todos eles têm uma estratégia de implementação típica para produzir primeiro o bytecode e depois executá-lo por meio de uma VM / intérprete. .
É mais provável que o foco esteja em quão "pesado", lento e de alta cerimônia é o processo de compilação. O CPython foi projetado para compilar o mais rápido possível, o mais leve possível, com o mínimo de cerimônia possível - o compilador faz muito pouca verificação e otimização de erros, para que possa executar rapidamente e em pequenas quantidades de memória, o que, por sua vez, permite seja executado de forma automática e transparente sempre que necessário, sem que o usuário precise saber que há uma compilação em andamento na maioria das vezes. Java e C # geralmente aceitam mais trabalho durante a compilação (e, portanto, não realizam a compilação automática) para verificar os erros mais detalhadamente e realizar mais otimizações. É um continuum de escamas cinzentas, não uma situação em preto ou branco,
Não existe linguagem interpretada. Se um intérprete ou um compilador é usado é apenas uma característica da implementação e não tem absolutamente nada a ver com o idioma.
Cada idioma pode ser implementado por um intérprete ou um compilador. A grande maioria dos idiomas possui pelo menos uma implementação de cada tipo. (Por exemplo, existem intérpretes para C e C ++ e compiladores para JavaScript, PHP, Perl, Python e Ruby.) Além disso, a maioria das implementações de linguagem moderna na verdade combina um intérprete e um compilador (ou até vários compiladores).
Uma linguagem é apenas um conjunto de regras matemáticas abstratas. Um intérprete é uma das várias estratégias de implementação concretas para um idioma. Esses dois vivem em níveis de abstração completamente diferentes. Se o inglês fosse um idioma digitado, o termo "idioma interpretado" seria um erro de tipo. A afirmação "Python é uma linguagem interpretada" não é apenas falsa (porque ser falsa implicaria que a afirmação faz sentido, mesmo que esteja errada), simplesmente não faz sentido , porque uma linguagem nunca pode ser definida como "interpretado".
Em particular, se você observar as implementações existentes no Python, estas são as estratégias de implementação que estão usando:
Você pode perceber que cada uma das implementações nessa lista (além de outras que eu não mencionei, como tinypy, Shedskin ou Psyco) tem um compilador. De fato, até onde eu sei, atualmente não existe uma implementação do Python que seja puramente interpretada, não existe uma implementação planejada e nunca houve essa implementação.
Não apenas o termo "linguagem interpretada" não faz sentido, mesmo que você a interprete como significando "linguagem com implementação interpretada", mas claramente não é verdade. Quem lhe disse isso, obviamente não sabe do que está falando.
Em particular, os .pyc
arquivos que você está vendo são armazenados em cache por códigos de código produzidos pelo CPython, Stackless Python ou Unladen Swallow.
Eles são criados pelo intérprete Python quando um .py
arquivo é importado e contêm o "bytecode compilado" do módulo / programa importado, com a idéia de que a "tradução" do código fonte para o bytecode (que só precisa ser feita uma vez) pode ser ignorado em import
s subsequentes, se o .pyc
for mais novo que o .py
arquivo correspondente , acelerando um pouco a inicialização. Mas ainda é interpretado.
Para acelerar o carregamento de módulos, o Python armazena em cache o conteúdo compilado dos módulos em .pyc.
O CPython compila seu código-fonte em "código de bytes" e, por razões de desempenho, armazena em cache esse código de bytes no sistema de arquivos sempre que o arquivo de origem é alterado. Isso torna o carregamento dos módulos Python muito mais rápido, porque a fase de compilação pode ser ignorada. Quando seu arquivo de origem é foo.py, o CPython armazena em cache o código de bytes em um arquivo foo.pyc ao lado da fonte.
No python3, o mecanismo de importação do Python é estendido para gravar e pesquisar arquivos de cache de código de bytes em um único diretório dentro de cada diretório de pacotes do Python. Este diretório será chamado __pycache__.
Aqui está um fluxograma descrevendo como os módulos são carregados:
Para maiores informações:
ref: PEP3147
ref: arquivos Python “compilados”
ISTO É PARA INICIANTES,
O Python compila automaticamente seu script no código compilado, chamado código de bytes, antes de executá-lo.
A execução de um script não é considerada uma importação e nenhum .pyc será criado.
Por exemplo, se você tiver um arquivo de script abc.py que importe outro módulo xyz.py , ao executar o abc.py , o xyz.pyc será criado desde que o xyz foi importado, mas nenhum arquivo abc.pyc será criado desde o abc. py não está sendo importado.
Se você precisar criar um arquivo .pyc para um módulo que não seja importado, poderá usar os módulos py_compile
e compileall
.
O py_compile
módulo pode compilar manualmente qualquer módulo. Uma maneira é usar a py_compile.compile
função nesse módulo interativamente:
>>> import py_compile
>>> py_compile.compile('abc.py')
Isso gravará o arquivo .pyc no mesmo local que o abc.py (você pode substituí-lo pelo parâmetro opcional cfile
).
Você também pode compilar automaticamente todos os arquivos em um diretório ou diretórios usando o módulo compileall.
python -m compileall
Se o nome do diretório (o diretório atual neste exemplo) for omitido, o módulo compila tudo o que é encontrado em sys.path
O Python (pelo menos a implementação mais comum) segue um padrão de compilação da fonte original em códigos de bytes e, em seguida, na interpretação dos códigos de bytes em uma máquina virtual. Isso significa (novamente, a implementação mais comum) não é um intérprete puro nem um compilador puro.
O outro lado disso, no entanto, é que o processo de compilação está oculto na maior parte - os arquivos .pyc são basicamente tratados como um cache; eles aceleram as coisas, mas você normalmente não precisa estar ciente delas. Ele os invalida e os recarrega automaticamente (recompila o código-fonte) quando necessário com base nos registros de data / hora do arquivo.
A única vez em que vi um problema com isso foi quando um arquivo de bytecode compilado de alguma forma obteve um carimbo de data / hora no futuro, o que significava que sempre parecia mais novo que o arquivo de origem. Como parecia mais novo, o arquivo de origem nunca foi recompilado; portanto, independentemente das alterações feitas, eles foram ignorados ...
O arquivo * .py do Python é apenas um arquivo de texto no qual você escreve algumas linhas de código. Quando você tenta executar este arquivo usando, diga "python filename.py"
Este comando chama a máquina virtual Python. A Máquina Virtual Python possui 2 componentes: "compilador" e "intérprete". O intérprete não pode ler diretamente o texto no arquivo * .py, portanto, esse texto é primeiro convertido em um código de bytes direcionado ao PVM (não hardware, mas PVM) . O PVM executa esse código de bytes. O arquivo * .pyc também é gerado, como parte da execução, que executa sua operação de importação no arquivo no shell ou em algum outro arquivo.
Se esse arquivo * .pyc já for gerado, toda vez que você executar / executar seu arquivo * .py, o sistema carregará diretamente o arquivo * .pyc, o que não precisará de nenhuma compilação (isso economizará alguns ciclos de máquina do processador).
Depois que o arquivo * .pyc é gerado, não há necessidade do arquivo * .py, a menos que você o edite.
O código Python passa por 2 estágios. O primeiro passo compila o código em arquivos .pyc, que na verdade é um bytecode. Em seguida, esse arquivo .pyc (bytecode) é interpretado usando o interpretador CPython. Por favor, consulte este link. Aqui, o processo de compilação e execução de código é explicado em termos fáceis.