¿Qué es una alternativa a execfile en Python 3?


Parece que cancelaron en Python 3 toda la manera fácil de cargar rápidamente un script eliminando execfile()

¿Hay una alternativa obvia que me falta?

Author: ideasman42, 2009-01-12

12 answers

Según la documentación , en lugar de

execfile("./filename") 

Use

exec(open("./filename").read())

Véase:

 260
Author: Pedro Vagner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-02 02:27:32

Se supone que solo debe leer el archivo y ejecutar el código usted mismo. 2a3 la corriente sustituye

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 haciendo que la depuración sea un poco sencillo.)

Véase:

 189
Author: Benjamin Peterson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-29 22:51:10

Como sugirió en la lista de correo python-dev recientemente, el módulo runpy podría ser una alternativa viable. Citando de ese mensaje:

Https://docs.python.org/3/library/runpy.html#runpy.run_path

import runpy
file_globals = runpy.run_path("file.py")

Hay diferencias sutiles con execfile:

  • run_path siempre crea un nuevo espacio de nombres. Ejecuta el código como un módulo, por lo que no hay diferencia entre globales y locales (por lo que solo hay un init_globals argumento). Se devuelven los globales.

    execfile ejecutado en el espacio de nombres actual o en el espacio de nombres dado. La semántica de locals y globals, si se da, era similar a los locales y globales dentro de una definición de clase.

  • run_path no solo puede ejecutar archivos, sino también huevos y directorios (consulte su documentación para obtener más detalles).

 41
Author: Jonas Schäfer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-17 10:06:15

Mientras que exec(open("filename").read()) se da a menudo como una alternativa a execfile("filename"), se pierde bastantes detalles que execfile soportado.

La siguiente función para Python3.x es lo más cerca que pude llegar a tener el mismo comportamiento que ejecutar un archivo directamente. Que coincide con la ejecución 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 la lectura binaria para evitar problemas de codificación
  • Garantizado para cerrar el archivo (Python3.x advierte sobre esto)
  • define __main__, algunos los scripts dependen de esto para comprobar si se están cargando como un módulo o no para eg. if __name__ == "__main__"
  • la configuración __file__ es mejor para los mensajes de excepción y algunos scripts usan __file__ para obtener las rutas de otros archivos en relación con ellos.
  • Toma argumentos globales y locales opcionales, modificándolos en su lugar como lo hace execfile, para que pueda acceder a cualquier variable definida leyendo las variables después de ejecutarlas.

  • A diferencia de Python2 execfile esto hace no modificar la corriente espacio de nombres por defecto. Para eso tienes que pasar explícitamente globals().

 34
Author: ideasman42,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-12 21:54:33

Podrías escribir tu propia función:

def xfile(afile, globalz=None, localz=None):
    with open(afile, "r") as fh:
        exec(fh.read(), globalz, localz)

Si realmente lo necesitabas...

 17
Author: Evan Fosmark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-30 02:09:04

Este es mejor, ya que toma los globales y locales de la persona que llama:

import sys
def execfile(filename, globals=None, locals=None):
    if globals is None:
        globals = sys._getframe(1).f_globals
    if locals is None:
        locals = sys._getframe(1).f_locals
    with open(filename, "r") as fh:
        exec(fh.read()+"\n", globals, locals)
 16
Author: Noam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-17 12:43:26

Si el script que desea cargar está en el mismo directorio que el que ejecuta, tal vez" import " hará el trabajo ?

Si necesita importar código dinámicamente, vale la pena mirar la función incorporada __ import__ y el módulo imp.

>>> import sys
>>> sys.path = ['/path/to/script'] + sys.path
>>> __import__('test')
<module 'test' from '/path/to/script/test.pyc'>
>>> __import__('test').run()
'Hello world!'

Test.py:

def run():
        return "Hello world!"

Si está utilizando Python 3.1 o posterior, también debe echar un vistazo a importlib.

 11
Author: ascobol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-26 17:11:05

Esto es lo que tenía (file ya está asignado a la ruta al archivo con el código fuente en ambos ejemplos):

execfile(file)

Esto es lo que lo reemplazé con:

exec(compile(open(file).read(), file, 'exec'))

Mi parte favorita: la segunda versión funciona bien en Python 2 y 3, lo que significa que no es necesario agregar lógica dependiente de la versión.

 6
Author: ArtOfWarfare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-07 13:39:03

Tenga en cuenta que el patrón anterior fallará si está utilizando declaraciones de codificación PEP-263 que no son ascii o utf-8. Necesita encontrar la codificación de los datos y codificarla correctamente antes de entregarlo a exec ().

class python3Execfile(object):
    def _get_file_encoding(self, filename):
        with open(filename, 'rb') as fp:
            try:
                return tokenize.detect_encoding(fp.readline)[0]
            except SyntaxError:
                return "utf-8"

    def my_execfile(filename):
        globals['__file__'] = filename
        with open(filename, 'r', encoding=self._get_file_encoding(filename)) as fp:
            contents = fp.read()
        if not contents.endswith("\n"):
            # http://bugs.python.org/issue10204
            contents += "\n"
        exec(contents, globals, globals)
 5
Author: Eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-13 00:43:54

Además, aunque no es una solución pura de Python, si está utilizando IPython (como probablemente debería de todos modos), puede hacer:

%run /path/to/filename.py

Que es igualmente fácil.

 3
Author: R S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-15 06:10:24

Solo soy un novato aquí, así que tal vez sea pura suerte si encuentro esto:

Después de intentar ejecutar un script desde el intérprete >>> con el comando

    execfile('filename.py')

Para el que obtuve un" NameError: nombre 'execfile' no está definido " Probé un

    import filename

Funcionó bien :-)

Espero que esto pueda ser útil y gracias a todos por los grandes consejos, ejemplos y todas esas piezas de código magistralmente comentadas que son una gran inspiración para los recién llegados !

Uso Ubuntu 16.014 LTS x64. Python 3.5.2 (por defecto, 17 de noviembre de 2016, 17:05: 23) [GCC 5.4.0 20160609] en linux

 2
Author: Claude,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-11 23:23:28

Localice la ruta de instalación de su carpeta (la tengo en C:\python34) a continuación, ejecutar en un shell cmd regular

   set path=%path%;c:\python34

Ahora cuando inicias un shell, muévete a C:\python34\myscripts y utilizar el comando clásico

 python filename.py 
 -2
Author: Weapon X,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-04 20:42:51