¿Cuál es una alternativa al archivo exec en Python 3?
Parece que cancelaron en Python 3 todas las formas sencillas de cargar rápidamente un script eliminando execfile()
.
¿Hay alguna alternativa obvia que me falta?
Según la documentación , en lugar de
execfile("./filename")
Usar
exec(open("./filename").read())
Ver:
- Novedades de Python 3.0
execfile
exec
Se supone que debes leer el archivo y ejecutar el código tú mismo. 2to3 reemplazos actuales
execfile("somefile.py", global_vars, local_vars)
como
with open("somefile.py") as f:
code = compile(f.read(), "somefile.py", 'exec')
exec(code, global_vars, local_vars)
(La llamada de compilación no es estrictamente necesaria, pero asocia el nombre del archivo con el objeto de código, lo que facilita un poco la depuración).
Ver:
- http://docs.python.org/release/2.7.3/library/functions.html#execfile
- http://docs.python.org/release/3.2.3/library/functions.html#compile
- http://docs.python.org/release/3.2.3/library/functions.html#exec
Si bien exec(open("filename").read())
a menudo se presenta como una alternativa execfile("filename")
, omite detalles importantes que la execfile
respaldan.
La siguiente función para Python3.x es lo más cercano que pude llegar a tener el mismo comportamiento que ejecutar un archivo directamente. Eso coincide con correr python /path/to/somefile.py
.
def execfile(filepath, globals=None, locals=None):
if globals is None:
globals = {}
globals.update({
"__file__": filepath,
"__name__": "__main__",
})
with open(filepath, 'rb') as file:
exec(compile(file.read(), filepath, 'exec'), globals, locals)
# Execute the file.
execfile("/path/to/somefile.py")
Notas:
Utiliza lectura de archivos binarios para evitar problemas de codificación.
Garantizado para cerrar el archivo (Python3.x advierte sobre esto).
Define
__main__
, algunos scripts dependen de esto para verificar si se están cargando como un módulo o no, por ejemplo.if __name__ == "__main__"
.La configuración
__file__
es mejor para mensajes de excepción y algunos scripts se utilizan__file__
para obtener las rutas de otros archivos relacionados con ellos.Toma argumentos globales y locales opcionales, modificándolos en el lugar al igual que
execfile
lo hace, para que pueda acceder a cualquier variable definida leyendo las variables después de la ejecución.A diferencia de Python2,
execfile
esto no modifica el espacio de nombres actual de forma predeterminada. Para eso tienes que pasar explícitamenteglobals()
&locals()
.