Ho letto che in CPython, lo stack dell'interprete (l'elenco delle funzioni Python chiamate per raggiungere questo punto) è mescolato con lo stack C (l'elenco delle funzioni C che sono state chiamate nel codice proprio dell'interprete). Se è così, allora come vengono implementati i generatori e le coroutine? Come si ricordano il loro stato di esecuzione? CPython copia lo stack di ogni generatore/coroutine su e da uno stack del sistema operativo? Oppure CPython mantiene semplicemente il frame dello stack più in alto del generatore sull'heap, dal momento che il generatore può cedere solo dal frame più in alto?Come vengono implementati generatori e coroutine in CPython?
risposta
L'istruzione yield
prende l'attuale contesto di esecuzione come chiusura e la trasforma in un oggetto vivente. Questo oggetto ha un metodo __iter__
che continuerà dopo questa dichiarazione di rendimento.
Quindi lo stack di chiamate viene trasformato in un oggetto heap.
È importante chiarire lo stack "hardware" C e lo stack Python sono cose completamente diverse, poiché la domanda confonde entrambi. La mia risposta chiarisce questo. (@Rudi - la tua risposta va bene, sto lasciando il commento in modo che anche altre persone arrivino qui a vedere quella parte) – jsbueno
La nozione che lo stack Python e lo stack C in un programma Python in esecuzione vengano mescolati può essere fuorviante.
Lo stack Python è qualcosa di completamente separato rispetto allo stack C utilizzato dall'interprete. Le strutture dati sullo stack Python sono in effetti oggetti "frame" Python completi (che possono anche essere introspected e avere alcuni attributi modificati in fase di esecuzione). Questo stack è gestito dalla macchina virtuale Python, che a sua volta viene eseguita in C e quindi ha un normale programma C, livello macchina, stack.
Quando si utilizzano generatori ed iteratori, l'interprete memorizza semplicemente il rispettivo oggetto frame da qualche altra parte rispetto allo stack del programma Python e lo spinge indietro quando riprende l'esecuzione del generatore. Questo "da qualche altra parte" è l'oggetto generatore stesso. Se si fa riferimento al metodo "successivo" o "invia" sull'oggetto generatore, ciò accade.
Questo è il tipo di risposta tecnica che desidero vedere di più in StackOverflow. Grazie! – glendon
L'ho cercato dopo aver letto questo, quindi se qualcun altro è interessato, ecco [implementazione CPython di generatori] (https://github.com/python/cpython/blob/master/Objects/genobject.c). Consiglio di leggere prima questa risposta, aiuta a capire cosa fa il codice. – spectras
Alcune risposte e commenti esistenti sostengono che Python mantiene uno "stack di programmi" completamente separato dallo stack C della VM. Questa affermazione è sbagliata.
Controllare il link: http://en.wikipedia.org/wiki/Stackless_Python
Stackless Python esiste ma non è mainstream. La comprensione è che la domanda è giusta.
- 1. Come vengono implementati malloc e gratuiti?
- 2. Come vengono implementati sbrk/brk in Linux?
- 3. Come vengono implementati gli array in Perl?
- 4. Come vengono implementati i vtables in C++ e C#?
- 5. Come vengono implementati i parser DOM?
- 6. Come vengono implementati i C# Generics?
- 7. Come vengono implementati i tipi di membri?
- 8. Come vengono implementati i riferimenti deboli?
- 9. Come vengono implementati i canali Go?
- 10. Come vengono implementati i blocchi try/catch?
- 11. Come vengono implementati CSS e DOM nel browser?
- 12. Come vengono implementati gli argomenti variabili in gcc?
- 13. Come vengono implementati i valori opzionali in Swift?
- 14. Pygame ritarda quando vengono implementati due giocatori
- 15. Come vengono implementati i comandi incorporati nella shell?
- 16. Come vengono implementati gli automatismi finiti nel codice?
- 17. Come vengono implementati gli elenchi collegati senza l'uso del puntatore?
- 18. Come vengono implementati i riferimenti nella JVM di Oracle?
- 19. Come vengono implementati i test di chat di Facebook?
- 20. CPython è l'interprete bytecode?
- 21. Come vengono implementati gli elenchi di argomenti di lunghezza variabile?
- 22. Come vengono implementati i turni a livello hardware?
- 23. Generatori e loop in Python
- 24. Generatori Mongoid e ActiveRecord
- 25. Differenze tra Coroutine e `goto`?
- 26. Come vengono implementati il segnale e gli slot sotto il cofano?
- 27. Coroutine in Java
- 28. Coroutine in C#
- 29. Come viene implementato string.find in CPython?
- 30. Quale generatore di parser utilizza CPython?
Ho accidentalmente risposto a me stesso quasi quattro anni dopo co-autore di un capitolo che include una spiegazione su come sono implementati generatori e coroutine: http://aosabook.org/en/500L/a-web-crawler-with-asyncio -coroutines.html –
Ottimo articolo, molto denso. –
Non correlato, ma ... come sei riuscito, in meno di 4 anni, a chiedere come sono stati implementati i generatori per scrivere un capitolo di un libro con Guido su questo argomento? :) – max