socialgekon.com
  • Principal
  • Talento Ágil
  • De Outros
  • Europa
  • Processo Interno
Tecnologia

Por que existem tantos Pythons?

Python é incrível.

Surpreendentemente, essa é uma afirmação bastante ambígua. O que quero dizer com 'Python'? Refiro-me à interface abstrata do Python? Quero dizer CPython, a implementação comum do Python (e não deve ser confundida com Cython, que são semelhantes em seus nomes)? Ou quero dizer algo totalmente diferente? Talvez eu esteja me referindo indiretamente a Jython, IronPython ou PyPy. Ou talvez eu tenha ido ao extremo e esteja falando sobre RPython ou RubyPython (ambos são coisas muito, muito diferentes).

Embora as tecnologias mencionadas acima sejam chamadas de maneiras semelhantes e referenciadas da mesma maneira, algumas delas servem a propósitos completamente diferentes (ou, pelo menos, operam de maneiras completamente diferentes).



Ao longo do meu tempo trabalhando com Python, me deparei com toneladas dessas ferramentas. * Ython. Mas não foi até recentemente que dediquei tempo para entender o que eles são, como funcionam e por que são necessários (à sua maneira).

Neste artigo, vou começar do zero e percorrer várias implementações Python, concluindo com uma introdução detalhada ao PyPy, que acredito ser o futuro da linguagem.

Tudo começa com a compreensão do que realmente é 'Python'.

Se você tem um bom entendimento de código binário, máquinas virtuais e similares, sinta-se à vontade para pule esta parte .

'O Python é interpretado ou compilado?'

Este é um ponto comum de confusão para iniciantes em Python.

A primeira coisa a saber é que 'Python' é uma interface. Existe um especificação sobre o que Python deve fazer e como devemos se comportar (como em qualquer interface). E existem várias implementações (como em qualquer interface).

A segunda coisa a saber é que 'interpretado' e 'compilado' são propriedades de um implementação , nenhum Interface .

Portanto, a questão não está bem formulada.

O Python é interpretado ou compilado? A questão não está muito bem formulada.

Dito isso, para a implementação mais comum (CPython: escrito em C, geralmente chamado apenas de 'Python', e certamente o que você está usando se não tem ideia do que estou falando), a resposta é: interpretado , com algumas peças compilado. CPython compilar ** código-fonte python para * bytecode , e naquele momento interpretar esse bytecode, executando-o na hora.

* Nota: não é uma 'compilação' no sentido tradicional da palavra. Normalmente, dizemos que 'compilar' é pegar o código de alto nível e convertê-lo em código binário. Mas é uma espécie de 'compilação'.

Vamos examinar a resposta um pouco mais de perto, pois ela nos permitirá entender alguns dos conceitos que surgirão mais adiante neste artigo.

Bytecode vs. Código binário

É muito importante entender a diferença entre bytecode e código binário (ou nativo), talvez melhor ilustrado com exemplos:

  • C compila em código binário, que é então executado diretamente em seu processador. Cada instrução diz à sua CPU para mover as coisas.
  • Java compila em bytecode, que é então executado na Java Virtual Machine (JVM), uma abstração de um computador que executa programas. Cada instrução é então tratada pela JVM, que interage com o seu computador.

Em resumo: o código binário é mais rápido, mas o bytecode é mais portátil e seguro .

O código binário parece diferente, dependendo da sua máquina, mas o bytecode parece o mesmo em todas as máquinas. Você poderia dizer que o código binário é otimizado para sua configuração.

Voltando ao CPython, o processo no conjunto de ferramentas acontece da seguinte maneira:

  1. CPython compila seu código Python para bytecode
  2. Esse bytecode é então executado na Máquina Virtual CPython

Os iniciantes presumem que o Python é compilado a partir dos arquivos .pyc. Há alguma verdade nisso: o arquivo .pyc é compilado em bytecode, que é então interpretado. Portanto, se você executou o código Python e já tem um arquivo .pyc disponível, ele será executado mais rápido na segunda vez, pois não será necessário recompilar o bytecode.

Máquinas virtuais alternativas: Jython, IronPython e mais

Como mencionei anteriormente, Python tem várias implementações. Novamente, como mencionei antes, o mais comum é CPython. Esta é uma implementação Python escrita em C e é considerada a implementação 'padrão'.

Mas e as alternativas? Um dos mais proeminentes é Jython , uma implementação em Java que usa a JVM. Enquanto CPython produz bytecode para ser executado na VM CPython, Jython produz java bytecode para ser executado na JVM (é a mesma coisa que é produzida ao compilar um programa Java).

“Por que eu usaria uma implementação alternativa?” Você pode perguntar. Bem, para começar, aqueles diferentes implementações funcionam bem com diferentes conjuntos de tecnologias .

CPython torna muito fácil escrever extensões C para seu código Python porque no final ele é executado por um interpretador C. Por outro lado, Jython torna mais fácil trabalhar com outros programas Java: você pode importar qualquer classe Java sem muito esforço , evocando e usando suas classes Java em seus programas Jython. (Observação: se você não pensou nisso em detalhes, é uma loucura. Estamos em um ponto onde você pode misturar e fragmentar diferentes linguagens e compilá-las em um único núcleo. Conforme mencionado por Rostin , programas que misturam código Fortran e C já existem há algum tempo. Portanto, é claro que isso não é necessariamente algo novo. Mas ainda é ótimo.)

Por exemplo, este é um código Jython válido:

[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_51 >>> from java.util import HashSet >>> s = HashSet(5) >>> s.add('Foo') >>> s.add('Bar') >>> s [Foo, Bar]

IronPython é outra implementação Python popular, escrita inteiramente em C # e voltada para a tecnologia .NET. Em particular, ele é executado com o que poderia ser chamado de Máquina Virtual .NET, Common Language Runtime (CLR) da Microsoft, comparável ao JVM.

Você poderia dizer que Jython: Java :: IronPython: C #. Eles são executados em suas respectivas VMs, você pode importar classes C # em seu código IronPython e classes Java de seu código Jython, etc.

É totalmente possível sobreviver sem nunca tocar em uma implementação Python não CPython. Mas existem vantagens obtidas com a mudança, muitas delas dependem da tecnologia que você usa. Você usa muitas linguagens baseadas em JVM? Jython pode ser para você. Tudo o que você faz é sobre a tecnologia .NET? Talvez você deva experimentar IronPython (e talvez já tenha).

A propósito: embora isso não seja um motivo para usar uma implementação diferente, observe que essas implementações diferem no comportamento além de como tratam seu código-fonte em Python. No entanto, essas diferenças são geralmente menores, dissolvendo-se ou emergindo com o tempo enquanto essas implementações estão em desenvolvimento ativo. Por exemplo, IronPython usar strings Unicode por padrão ; No entanto, CPython, por padrão usa ASCII para versões 2.x (falha com um erro de codificação UnicodeEncodeError para caracteres não ASCII), mas suporta strings Unicode por padrão para as versões 3.x .

Compilação Just-in-Time: PyPy e o Futuro

Portanto, temos uma implementação Python escrita em C, uma em Java e outra em C #. O próximo passo lógico: uma implementação Python escrita em… Python. (O leitor instruído achará essa notação um pouco enganosa.)

É aqui que as coisas ficam confusas. Primeiro, vamos discutir a compilação Just-in-Time (JIT).

JIT: O porquê e como

Lembre-se de que o código binário é muito mais rápido do que o bytecode. Bem, e se pudéssemos compilar algumas partes do nosso bytecode e depois executá-lo como código nativo? Teríamos que pagar algum preço ao compilar para bytecode (por exemplo, tempo), mas se o resultado fosse mais rápido, seria ótimo! Essa é a motivação por trás da compilação JIT, uma técnica híbrida que combina os benefícios de interpretadores e compiladores. Em termos básicos, o JIT quer usar a compilação para acelerar um sistema interpretado.

Por exemplo, uma abordagem comum adotada pela compilação JIT:

  1. Identifique o bytecode que é executado com freqüência.
  2. Compile para código binário.
  3. Armazene o resultado em cache.
  4. Contanto que o mesmo bytecode seja executado, em vez de usá-lo, execute o código binário pré-compilado e obtenha os benefícios (por exemplo, aumentos de velocidade)

É disso que se trata o PyPy: trazer JIT para Python (consulte o Apêndice para ver os esforços anteriores). Existem, é claro, outros objetivos: o PyPy visa ser multiplataforma, com baixo consumo de memória e independente de todas as tecnologias. Mas o JIT realmente se vende. Na média de um punhado de testes de tempo, é dito que melhora o desempenho por um fator de 6,27 . Para uma discussão mais aprofundada, consulte este gráfico do PyPy Speed ​​Center :

PyPy é difícil de entender

PyPy tem um grande potencial e, neste ponto, é muito compatível com CPython (como este que pode executar Flask, Django, etc. )

Mas há muita confusão em torno do PyPy (veja, por exemplo, esta proposta absurda de criar um PyPyPy ... ) Na minha opinião, isso ocorre principalmente porque PyPy é atualmente duas coisas:

  1. Um interpretador Python escrito em RPython (não Python (eu menti antes). RPython é um subconjunto de Python com tipos estáticos. Em Python, é ' praticamente impossivel ”Raciocine rigorosamente sobre os tipos (Por que é tão difícil? Bem, considere o fato de que:

    x = random.choice([1, 'foo'])

    seria um código Python válido (créditos para Gesto ) Que tipo é x? Como podemos raciocinar sobre os tipos de variáveis ​​quando os tipos nem mesmo são estritamente impostos?). Com RPython, você sacrifica alguma flexibilidade, mas em troca é muito mais fácil raciocinar sobre gerenciamento de memória e assim por diante, o que permite otimizações.

  2. Um compilador que compila o código RPython para vários fins e adiciona JIT. A plataforma padrão é C, por exemplo, um compilador RPython-para-C, mas você também pode apontar para JVM e outros.

Apenas para maior clareza, vou me referir a eles como PyPy (1) e PyPy (2).

Por que você precisaria dessas duas coisas e por que sob o mesmo teto? Pense desta forma: PyPy (1) é um interpretador escrito em RPython. Portanto, ele pega o código Python do usuário e o compila em bytecode. Mas o próprio interpretador (escrito em RPython) deve ser interpretado por outra implementação Python para ser executado, certo?

Bem, poderíamos apenas usar CPython para executar o interpretador. Mas isso não seria rápido o suficiente.

Em vez disso, a ideia é usar PyPy (2) (também conhecido como RPython Toolchain) -RPython toolset) para compilar o interpretador PyPy para o código que outra plataforma (por exemplo, C, JVM ou CLI) pode executar em nossa máquina, adicionando também JIT. É mágico: o PyPy adiciona dinamicamente JIT a um interpretador, gerando seu próprio compilador! (Novamente, isso é loucura: estamos compilando um interpretador e adicionando outro compilador separado separadamente.)

No final, o resultado é um executável autônomo que interpreta o código-fonte do Python e explora as otimizações JIT. Que é exatamente o que queríamos! É um grande bocado, mas talvez este diagrama ajude:

Para reiterar, a verdadeira beleza do PyPy é que podemos escrever um punhado de interpretadores Python diferentes em RPython sem nos preocuparmos com o JIT (exceto por algumas sugestões). PyPy então implementaria o JIT para nós usando o conjunto de ferramentas RPython / PyPy (2).

Na verdade, se formos ainda mais abstratos, você poderia, teoricamente, escrever um intérprete para qualquer linguagem, alimente PyPy com ela e obtenha um JIT para essa linguagem. Isso ocorre porque o PyPy se concentra na otimização do interpretador atual, e não nos detalhes do idioma que está interpretando.

Você poderia, teoricamente, escrever um intérprete para * qualquer * linguagem, alimentar o PyPy com ele e obter um JIT para essa linguagem.

Vagando um pouco, gostaria de mencionar que o JIT em si é absolutamente fascinante. Ele usa uma técnica chamada rastreamento (ou rastreamento), que é realizada da seguinte maneira :

  1. Execute o interpretador e interprete tudo (sem adicionar nenhum JIT)
  2. Aprimore ligeiramente o código interpretado.
  3. Identifique as operações que você executou antes.
  4. Compile esses pedaços em código binário.

Para mais informacao, este documento é altamente acessível e muito interessante.

Para concluir: usamos o compilador PyPy RPython-a-C (ou outra plataforma) para compilar o interpretador PyPy RPython implementado.

Concluindo

Por que é tão legal? Por que vale a pena perseguir essa ideia maluca? Creio que Alex Gaynor ele descreveu muito bem em seu Blog : '[PyPy é o futuro] porque oferece melhor velocidade, mais flexibilidade e é uma plataforma melhor para o crescimento do Python.'

Em resumo:

  • É rápido porque compila o código-fonte para o código nativo (usando JIT).
  • É flexível porque adiciona JIT ao seu intérprete com muito pouco trabalho extra.
  • É flexível (novamente) porque você pode escrever seus interpretadores em RPython , o que torna mais fácil estender do que, digamos, C na verdade é tão fácil que existe um tutorial para escrever seus próprios intérpretes .

Apêndice: Outros nomes que você pode ter ouvido

  • Python 3000 (Py3k) : nome alternativo para Python 3.0, um major, versões compatíveis com versões anteriores Lançamento Python que entrou em cena em 2008 . A equipe Py3k previu que demoraria cinco anos para que esta versão seja totalmente adotada. E enquanto a maioria (Cuidado: dito ser anedótico) À medida que os desenvolvedores Python continuam a usar o Python 2.x, a consciência do Py3k entre as pessoas está aumentando.
  • Cython : um superconjunto Python que inclui ligações (ou ligações) para chamar funções C.
    • Objetivo: permitir que você escreva extensões C para o seu código Python
    • Também permite que você adicione tipos de variáveis ​​estáticas ao seu código Python, permitindo que ele seja compilado e atinja um desempenho semelhante ao do C.
    • É semelhante ao PyPy, mas não é o mesmo. Nesse caso, você é forçado a escrever o código do usuário antes de passá-lo para o compilador. Com PyPy, você simplesmente escreve o código Python, e o compilador lida com qualquer otimização.
  • Numba :: um 'compilador just-in-time especializado' que adiciona JIT ao código Python anotado. Em termos mais básicos, você fornece algumas dicas e acelera partes do seu código. Numa vem como parte da distribuição Anaconda , um conjunto de pacotes para gerenciamento e análise de dados.
  • IPython : muito diferente de tudo o que discutimos até agora. É um ambiente de processamento para Python. Interativo e com suporte para ferramentas gráficas e experiência de navegador, etc.
  • Psyco : uma módulo de extensão python , e um dos primeiros esforços do JIT em Python. De qualquer forma, foi marcado como 'Sem manutenção e morto' . Na verdade, o principal desenvolvedor do Psyco, Armin Rigo, agora trabalha na PyPy .

Links de idiomas

  • RubyPython - Uma ponte entre as máquinas virtuais Ruby e Python. Permite que você incorpore o código Python em seu código Ruby. Você define onde o Python começa e termina, e o RubyPython calcula os dados entre as VMs.
  • PyObjc : links de linguagem entre Python e Objective-C, atuando como uma ponte entre eles. Praticamente, isso significa que você pode usar bibliotecas Objective-C (incluindo tudo que você precisa para criar aplicativos OS X) de seu código Python e módulos Python de seu código Objective-C. Nesse caso, CPython deve ser escrito em C, que é um subconjunto de Objective-C.
  • PyQt : enquanto o PyObjc oferece uma interface para os componentes gráficos do OS X, o PyQt faz o mesmo com o framework QT, permitindo que você crie interfaces gráficas completas, acesso a bancos de dados SQL, etc. Outra ferramenta que visa trazer a simplicidade do Python para outros frameworks.

Frameworks JavaScript

  • pijamas - Uma estrutura para criar aplicativos da web e de desktop em Python. Inclui um compilador Python-para-Javascript, um conjunto de widgets e mais algumas ferramentas.
  • Brython : uma máquina virtual Python escrita em JavaScript para permitir que o código Py3k seja executado em navegadores.


Conteúdo traduzido por Pablo Fabregat, sócio de TransBunko , um mercado de traduções técnicas.

Apresentando Battlescripts: Bots, Ships, Mayhem!

Web Front-End

Apresentando Battlescripts: Bots, Ships, Mayhem!
O impacto do Brexit no setor de serviços financeiros

O impacto do Brexit no setor de serviços financeiros

Processos Financeiros

Publicações Populares
Melhores práticas de fusões e aquisições na América Latina
Melhores práticas de fusões e aquisições na América Latina
As 25 melhores predefinições do Lightroom Mobile para fotos impressionantes do iPhone
As 25 melhores predefinições do Lightroom Mobile para fotos impressionantes do iPhone
EUA: corrida para prefeito de Honolulu segue para segundo turno
EUA: corrida para prefeito de Honolulu segue para segundo turno
Como fazer autenticação JWT com um Angular 6 SPA
Como fazer autenticação JWT com um Angular 6 SPA
Como editar fotos no iPhone com iOS Photos
Como editar fotos no iPhone com iOS Photos
 
React Test-driven Development: From User Stories to Production
React Test-driven Development: From User Stories to Production
Criação de uma API REST segura em Node.js
Criação de uma API REST segura em Node.js
Um guia de campo para DesignOps
Um guia de campo para DesignOps
Donald Trump encontra o Papa Francisco no Vaticano, jura não esquecer sua mensagem
Donald Trump encontra o Papa Francisco no Vaticano, jura não esquecer sua mensagem
Automação no Selenium: Modelo de objeto de página e fábrica de página
Automação no Selenium: Modelo de objeto de página e fábrica de página
Categorias
NutriçãoVida DesignerGestão De EngenhariaPessoas E Equipes De ProdutoFamíliaCiclo De Vida Do ProdutoAprendendoFerramentas E TutoriaisKpis E AnálisesFuturo Do Trabalho

© 2023 | Todos Os Direitos Reservados

socialgekon.com