Читать книгу El gran libro de Python - Marco Buttu - Страница 58
La Python Virtual Machine
ОглавлениеEn realidad, la instalación de Python no contiene solo un intérprete, sino también un compilador. Cuando un programa es ejecutado, Python compila todos los módulos importados que no han sido modificados desde la última vez en que han sido compilados. Este proceso genera una nueva representación (de nivel bajo) del código, denominada bytecode, la cual es leída y ejecutada por la Python Virtual Machine (PVM). Por tanto no es el código Python lo que se ejecuta, sino el código en bytecode, por lo que el verdadero intérprete, en realidad, es la PVM, la cual ejecuta las instrucciones en bytecode una a una.
A continuación, un ejemplo de instrucciones en bytecode relacionadas con una función que devuelve el cuadrado de un número:
NOTA
Para más información acerca del significado de las instrucciones en byte- code, podemos consultar la documentación en línea del módulo dis: http://docs.python.org/py3k/library/dis.html. Recordad que todos los detalles de implementación tratados en este libro se refieren a CPython.
Cuando se importa un módulo, su versión compilada, si no se expresa de otro modo, se guarda en el sistema de archivos para que pueda ser reutilizada durante las sucesivas ejecuciones del programa, sin que sean necesarias compilaciones posteriores (ver PEP-3147):
Los archivos compilados en bytecode pueden ser ejecutados directamente:
NOTA
En el ejemplo anterior hemos usado diferentes comandos típicos de Unix. Veamos el significado de algunos de ellos. El carácter #, como podemos imaginar, se usa para iniciar un comentario. La instrucción echo "print(_ _name_ _)" > m.py escribe la cadena de texto print(_ _name_ _) en el archivo m.py (si el archivo no existe, lo crea y si existe, lo sobrescribe). El comando ls lista informaciones acerca del archivo y muestra el contenido de los directorios. Las explicaciones del resto de los comandos y de sus opciones forman parte del Apéndice A.
Los módulos Python importados tienen los atributos _ _file_ _ y _ _cached_ _, que son cadenas que representan, respectivamente, el nombre del archivo fuente y el del importado:
NOTA
En la sección Los módulos del Capítulo 3 veremos que algunos módulos (inte- grados y paquetes de espacios de nombres) no se pueden reconducir a un archivo y, por tanto, no tienen los atributos _ _file_ _ y _ _cached_ _.
La etiqueta (tag) que identifica la implementación del intérprete y la versión de Python la da imp.get_tag():
El módulo imp también nos permite obtener el nombre del archivo fuente a partir del nombre del archivo importado y viceversa:
Cuando un módulo Python se ejecuta como script, su bytecode no se guarda en el disco:
NOTA
El comando rm elimina un archivo o un directorio del sistema de archivos. En el caso de un directorio, es preciso utilizar la opción -r.
Sin embargo, podemos solicitar explícitamente su almacenamiento. Para ello, se utiliza la opción -m y se pasa al intérprete el nombre del módulo y no el del archivo:
Si en combinación con la opción -m se utiliza la opción -O, entonces se genera un byte-code optimizado (se eliminan las instrucciones assert), el cual se guarda en un archivo con sufijo .pyo:
NOTA
Ante dos archivos binarios file_A y file_B, el comando diff file_A file_B no muestra ninguna salida si ambos archivos son idénticos; si no, indica que son distintos.
También podemos elegir no guardar en el sistema de archivos las versiones compiladas de los módulos importados. Para ello, podemos utilizar la opción -B:
o bien podemos asignar a la variable de entorno PYTHONDONTWRITEBYTECODE el valor true:
o bien podemos hacerlo cuando el programa se está ejecutando, escribiendo sys.dont_write_bytecode = True: