principio de ue5python
1.1python primero compila el código (archivo .py) en código de bytes y lo entrega a la máquina virtual de código de bytes. Luego, el intérprete ejecuta las instrucciones de código de bytes una por una desde el objeto PyCodeObject compilado. p>Y ejecute la instrucción de código de bytes en el contexto actual para completar la ejecución del programa. El objeto PyCodeObject
contiene instrucciones de código de bytes y toda la información estática del programa, pero no incluye información dinámica cuando el programa se está ejecutando - entorno de ejecución (PyFrameObject)
2. Bytecode
p>El código de bytes en el programa intérprete de Python corresponde al objeto PyCodeObject
. El archivo pyc es la representación del código de bytes en el disco
2.1 En su conjunto: en el sistema operativo, la ejecución de un programa es inseparable de dos conceptos: proceso y subproceso. PyInterpreterState y
PyTreadState se utilizan para simular procesos y subprocesos respectivamente, es decir, cada PyThreadState corresponde a una pila de cuadros y el intérprete de Python cambia entre múltiples subprocesos. Cuando el intérprete de Python comience a ejecutarse, realizará algunas operaciones de inicialización y finalmente ingresará a la función PyEval_EvalFramEx. La función de esta función es leer continuamente el código de bytes compilado y ejecutarlo uno por uno, similar al proceso de ejecución de instrucciones de la CPU. El interior de la función
es principalmente una estructura de interruptor, que ejecuta diferentes códigos según diferentes códigos de bytes.
3..archivo pyc
Python test.py creará un objeto PyCodeObject al cargar el módulo, y al importar
Python test.py creará una prueba. py Compilado en código de bytes e interpretado para su ejecución, pero test.pyc no se generará
Si test.py se carga con otros módulos, como importaciones, no se creará ningún archivo pyc.
Si test.py se carga junto con otros módulos, como import urlib2, Python compilará urlib2.py en código de bytes, generará urlib2.pyc y luego interpretará el código de bytes
Si Si queremos generar test.pyc, podemos usar el módulo integrado de Python, py_compile.
Al cargar un módulo, si existen tanto .py como pyc, Python intentará usar .pyc; si .pyc se compiló antes de modificar .py, .py se volverá a compilar y .pyc se actualizará; .
PyCodeObject
El resultado de la compilación del código Python es el objeto PyCodeObject
typedef struct {
PyObject_HEAD
int co_argcount /* Número de parámetros de posicionamiento */
int co_nlocals /* Número de variables locales*/
int co _stacksize/* Tamaño de pila*/
int co_flags;
PyObject *coo_code; /* Secuencia de instrucciones de código de bytes*/
PyObject *coo_consts /* Colección de todas las constantes*/
PyObject *coo_ nombres /* La colección de todos los nombres de símbolos */
PyObject *coo_varnames; /* La colección de nombres de variables locales*/
PyObject *coo_freevars /* La colección de nombres de variables utilizadas por cierre*/
PyObject *co_cellvars /* Colección de nombres de variables a las que hacen referencia funciones anidadas internas*/
/* El resto no está incluido en hash/cmp */
PyObject * co_filename /* El nombre del archivo donde se encuentra el código */
PyObject *co_name /* Nombre de la función | p>int co_firstlineno; /* Bloque de código en el archivo El número de primera línea de */
PyObject *co_lnotab /* Correspondencia entre instrucciones de código de bytes y números de línea*/
void * coo_zombieframe; /* Sólo se utiliza optimización (ver /* Sólo para optimización (ver frameobject.c) */
}PyCodeObject;
5. Formato de archivo .pyc
Cargando el módulo, el objeto PyCodeObject correspondiente al módulo se escribirá en el archivo .pyc
6 Analizando el código de bytes
6.1 Análisis de PyCodeObject
Python proporciona. una función de compilación incorporada, utilizada para compilar código Python y ver objetos PyCodeObject
6.2 Formato de secuencia de instrucciones co_code
opcode oparg opcode opcode oparg ....
1 palabra Sección 2 Byte 1 Byte 1 Byte 2 Byte
El módulo dis integrado de Python analizará co_code
Ejecutar bytecode
Explicación de Python La El principio del intérprete de Python es simular la ejecución de un programa ejecutable en una máquina X86. Su marco de pila de tiempo de ejecución es el siguiente
El principio del intérprete de Python es simular el comportamiento anterior. Cuando se produce una llamada a una función, se crea un nuevo marco de pila, que corresponde a la implementación de Python del objeto PyFrameObject.
El objeto PyFrameObject crea información dinámica cuando el programa se está ejecutando, es decir, el entorno de ejecución
7.1 PyFrameObject
typedef struct _frame{
PyObject_VAR_HEAD // ¡El tamaño de la "pila de tiempo de ejecución" no está definido!
struct _frame *f_back; // El marco anterior en la cadena del entorno de ejecución, muchos PyFrameObjects están vinculados aquí para formar la cadena del entorno de ejecución
PyCodeObject *f_code; , el marco es este. Objeto PyCodeObject, este marco es el contexto de este objeto PyCodeObject
PyObject *f_builtins; //espacio de nombres incorporado
PyObject *f_globals; //espacio de nombres global
PyObject *f_locals;
PyObject **f_valuestack; //la parte inferior de la "pila de tiempo de ejecución"
PyObject **f_stacktop; //la parte superior de la "pila de tiempo de ejecución" p >
//...
int f_lasti; //Desplazamiento de la instrucción de código de bytes anterior en f_code
int f_lineno; //Byte actual Líneas de código
//...
// Memoria dinámica, espacio requerido para mantenimiento (variables locales + colección de objetos unitarios + colección de objetos libres + pila de tiempo de ejecución)
PyObject *f_localsplus[ 1];
}PyFrameObject;
Cada objeto PyFrameObject mantiene un objeto PyCodeObject, que indica el objeto de espacio de memoria dinámica y la fuente en cada PyFrameObject El código en el código corresponde.