Anche io ho avuto lo stesso problema nel capire come CPython, JPython, IronPython, PyPy siano diversi l'uno dall'altro.
Quindi, sono disposto a chiarire tre cose prima di iniziare a spiegare:
- Python : è un linguaggio, afferma / descrive solo come comunicare / esprimersi all'interprete (il programma che accetta il tuo codice python).
- Implementazione : si tratta di come l'interprete è stato scritto, in particolare, in quale lingua e cosa finisce per fare .
- Bytecode : è il codice che viene elaborato da un programma, di solito indicato come una macchina virtuale, piuttosto che dalla macchina "reale", il processore hardware.
CPython è l'implementazione, che è stata scritta in linguaggio C. Finisce per produrre bytecode (set di istruzioni basato su stack-machine) che è specifico di Python e quindi lo esegue. Il motivo per convertire il codice Python in un bytecode è perché è più semplice implementare un interprete se assomiglia alle istruzioni della macchina. Tuttavia, non è necessario produrre alcuni bytecode prima dell'esecuzione del codice Python (ma CPython produce).
Se vuoi guardare il bytecode di CPython, puoi farlo. Ecco come puoi:
>>> def f(x, y): # line 1
... print("Hello") # line 2
... if x: # line 3
... y += x # line 4
... print(x, y) # line 5
... return x+y # line 6
... # line 7
>>> import dis # line 8
>>> dis.dis(f) # line 9
2 0 LOAD_GLOBAL 0 (print)
2 LOAD_CONST 1 ('Hello')
4 CALL_FUNCTION 1
6 POP_TOP
3 8 LOAD_FAST 0 (x)
10 POP_JUMP_IF_FALSE 20
4 12 LOAD_FAST 1 (y)
14 LOAD_FAST 0 (x)
16 INPLACE_ADD
18 STORE_FAST 1 (y)
5 >> 20 LOAD_GLOBAL 0 (print)
22 LOAD_FAST 0 (x)
24 LOAD_FAST 1 (y)
26 CALL_FUNCTION 2
28 POP_TOP
6 30 LOAD_FAST 0 (x)
32 LOAD_FAST 1 (y)
34 BINARY_ADD
36 RETURN_VALUE
Ora diamo un'occhiata al codice sopra. Le righe da 1 a 6 sono una definizione di funzione. Nella riga 8, importiamo il modulo 'dis' che può essere usato per visualizzare il bytecode Python intermedio (o si può dire, disassemblatore per bytecode Python) che viene generato da CPython (interprete).
NOTA : ho ottenuto il collegamento a questo codice dal canale IRC #python: https://gist.github.com/nedbat/e89fa710db0edfb9057dc8d18d979f9c
E poi, c'è Jython, che è scritto in Java e finisce per produrre codice byte Java. Il codice byte Java viene eseguito su Java Runtime Environment, che è un'implementazione di Java Virtual Machine (JVM). Se questo è confuso, sospetto che tu non abbia idea di come funzioni Java. In parole povere, il codice Java (il linguaggio, non il compilatore) è preso dal compilatore Java e genera un file (che è il codice byte Java) che può essere eseguito solo usando un JRE. Questo viene fatto in modo che, una volta compilato il codice Java, possa essere portato su altre macchine nel formato del codice byte Java, che può essere eseguito solo da JRE. Se questo è ancora confuso, allora potresti voler dare un'occhiata a questa pagina web .
Qui, potresti sospettare che il bytecode di CPython sia portatile come Jython, sospetto di no. Il bytecode prodotto nell'implementazione di CPython era specifico di quell'interprete per rendere più semplice l'ulteriore esecuzione del codice (ho anche il sospetto che, tale produzione intermedia di bytecode, solo per la facilità con cui l'elaborazione viene eseguita in molti altri interpreti).
Quindi, in Jython, quando compili il tuo codice Python, finisci con il codice byte Java, che può essere eseguito su una JVM.
Allo stesso modo, IronPython (scritto in linguaggio C #) compila il codice Python in Common Language Runtime (CLR), che è una tecnologia simile rispetto a JVM, sviluppata da Microsoft.