python python-3.x

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



python-3.x (12)

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

%run /path/to/filename.py

Lo que es igualmente fácil.

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 estoy perdiendo?


Como se sugirió recientemente en la lista de runpy python-dev , 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 para 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 (razón por la cual solo hay un argumento init_globals ). Los globales son devueltos.

    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, fue 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 la documentación para obtener detalles).


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)


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

execfile(file)

Esto es lo que lo reemplacé con:

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

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


Mientras que exec(open("filename").read()) execfile("filename") exec(open("filename").read()) menudo se ofrece como una alternativa a execfile("filename") , se execfile algunos detalles que execfile admite.

La siguiente función para Python3.x es lo más cerca que puedo llegar a tener el mismo comportamiento que ejecutar un archivo directamente. Eso coincide con la ejecución de 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 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 de __file__ es más agradable para los mensajes de excepción y algunos scripts usan __file__ para obtener las rutas de otros archivos relacionados con ellos.
  • toma los argumentos opcionales globales y locales, modificándolos in situ como execfile hace execfile , para que pueda acceder a cualquier variable definida leyendo las variables después de ejecutar.

  • A diferencia del execfile de execfile este no modifica el espacio de nombres actual de forma predeterminada. Para eso tienes que pasar explícitamente en globals() .


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 necesitas ...


Se supone que debes leer el archivo y ejecutar el código tú mismo. 2to3 reemplaza actual

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 de archivo con el objeto de código, lo que facilita la depuración).

Ver:


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

Si necesita importar dinámicamente el código, vale la pena mirar la función __ 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 debería echar un vistazo a importlib .


Solo soy un novato aquí, así que quizás sea pura suerte si encuentro esto:

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

execfile(''filename.py'')

para lo cual obtuve un "NameError: name ''execfile'' no está definido" Probé un muy básico

import filename

funcionó bien :-)

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

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


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. Debe encontrar la codificación de los datos y codificarlos correctamente antes de entregarlos 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)


localice la ruta de instalación de su carpeta (la tengo en C: / python34) y luego ejecútela en un shell cmd normal

set path=%path%;c:/python34

ahora, cuando inicie un shell, vaya a C: / python34 / myscripts y use el comando clásico

python filename.py