Como o Python Runtime realmente funciona?

26

Eu tenho alguns problemas para entender o conceito de a runtime library, especialmente o Python. Então, eu escrevi um programa python olá mundo e pretendo executá-lo, então eu escrevo python ./hello_world.py.

Quais etapas acontecem entre eu pressionar o botão Enter e o código da máquina gerado a partir do meu código python sendo executado na minha CPU? E como isso se relaciona com o sistema de tempo de execução Python e / ou biblioteca?

hgiesel
fonte
Esses dois threads fornecem uma excelente visão sobre o tempo de execução do Python - o Python é interpretado, compilado ou ambos? & Python é interpretado (como Javascript ou PHP)? . Tempo de execução e biblioteca de tempo de execução não são os mesmos. Mapeando-o para o mundo .NET que eu conheço - o Common Language Runtime (CLR) e o Framework / Base Class Library (FCL / BCL) não são os mesmos.
RBT

Respostas:

33

Por mais diversificados que sejam, existem alguns conceitos comuns que todas as linguagens de programação modernas sérias compartilham. Dois deles são o núcleo da resposta para suas perguntas acima.

Quais etapas acontecem entre eu pressionar o botão Enter e o código da máquina gerado a partir do meu código python sendo executado na minha CPU?

O código é analisado, analisado e alimentado em um intérprete. Isso é tudo sobre uma área muito importante da ciência da computação conhecida como teoria dos compiladores . Um compilador é um programa que converte código de um idioma (seu código-fonte) para outro idioma (normalmente código de máquina, embora existam "transpilers" que traduzem de um idioma de alto nível para outro). Este é um tópico realmente enorme que você poderia passar anos pesquisando, mas aqui está a versão básica:

O compilador começa com um analisador , uma rotina que lê seu código-fonte e aplica as regras de sintaxe da linguagem a ele para descobrir se faz sentido como código Python (no seu caso) válido. Caso contrário, o analisador emitirá um erro e o compilador falhará, mas, se o fizer, o analisador emitirá o que é conhecido como Árvore de Sintaxe Abstrata, ou AST, abreviado. O AST é uma estrutura de dados em árvore cujos nós contêm um elemento da sintaxe. Por exemplo, se você disser x = 5, poderá terminar com um BinaryExpressionnó com um operatorvalor de =, um Leftvalor de ReferenceExpression(x)e um Rightvalor de IntegerLiteralExpression(5). Todo o seu programa pode ser representado por uma grande árvore como esta.

Depois que o analisador produz um AST, a segunda fase é a análise semântica . Em inglês simples, isso significa "descobrir o que esse AST significa". Ele verifica o AST para determinar se você fez algo ilegal, embora seja uma análise válida (por exemplo, tentando chamar uma função de 1 argumento com 3 argumentos) e gera erros se você o fizer. Caso contrário, ele analisa o AST e realiza edições para facilitar a compreensão de uma máquina.

A terceira fase é a geração de código. Depois de ter um AST totalmente analisado, simplificado e válido, você o alimenta no gerador, que percorre o AST e produz código no idioma de saída. Este é o seu produto acabado.

Com o Python, ele usa um intérprete em vez de um compilador. Um intérprete funciona exatamente da mesma maneira que um compilador, com uma diferença: em vez da geração de código, ele carrega a saída na memória e a executa diretamente no seu sistema. (Os detalhes exatos de como isso acontece podem variar bastante entre diferentes idiomas e diferentes intérpretes.)

E como isso se relaciona com o sistema de tempo de execução Python e / ou biblioteca?

Todos os idiomas, exceto os mais simples, vêm com um conjunto de funções predefinidas que são importantes para uma grande porcentagem de usuários e que dificilmente seriam implementados por um motivo ou outro. O código deles pode chamar essas funções sem precisar de bibliotecas de terceiros. (Por exemplo, em Python, você printenvia uma saída para stdout. Boa sorte implementando isso por conta própria!) Esse conjunto de funções geralmente é coletado em uma biblioteca compartilhada na qual o código pode ser chamado em tempo de execução, e é por isso que é conhecido como a biblioteca de tempo de execução do idioma ou simplesmente "o tempo de execução" para abreviar.

Mason Wheeler
fonte
Então, meu código é alimentado para outro programa (o sistema de tempo de execução Python) que faz tudo isso e termina quando meu código termina (e após a limpeza, é claro)?
hgiesel
@ hgiesel Eu acredito que, no caso de Python, o intérprete faz parte do tempo de execução. Este não é o caso de todos os idiomas. é claro, mas é bastante comum entre idiomas interpretados.
Mason Wheeler
5

A implementação padrão do Python é uma máquina virtual de código de bytes. Isso significa que o código da máquina (códigos de operação do conjunto de códigos de operação do seu processador) não é gerado a partir do seu programa. Os códigos de operação são selecionados apenas nos códigos de operação que já foram compilados na máquina virtual enquanto a VM interpreta o código de bytes.

Como o seu programa é transformado em código de bytes, em primeiro lugar, é uma pergunta um pouco diferente, mas a resposta curta é "através da compilação, como qualquer outra tradução de idioma descendente".

Kilian Foth
fonte