¿Qué sucederá si modifico un script de Python mientras se está ejecutando?

8 minutos de lectura

avatar de usuario
wong2

Imagine un script de python que tardará mucho en ejecutarse, ¿qué sucederá si lo modifico mientras se ejecuta? ¿Será diferente el resultado?

  • El programa se carga en su memoria principal. Si cambia el archivo de origen, no pasa nada. Imagina que la CPU lee las instrucciones del disco duro…

    – Félix Kling

    14 de marzo de 2011 a las 9:50

  • @Felix: Eso se llama “Ejecutar en el lugar” (XIP).

    – Ignacio Vázquez-Abrams

    14 de marzo de 2011 a las 9:52

  • Puede recargar dinámicamente el código de los módulos, consulte stackoverflow.com/questions/437589/…

    – Iliyan Bobev

    9 oct 2012 a las 18:45

  • Tenga en cuenta que los archivos por lotes de Windows hacer ejecutar en su lugar, por lo que esta no es una pregunta hipotética, hay lenguajes que se comportan de esta manera.

    – yoyó

    8 de agosto de 2018 a las 21:03

  • ¿Sigue siendo así si tengo varios archivos .py con código fuente y el programa llama a estos diferentes archivos/clases durante el tiempo de ejecución? todavia se usa la version original? ¿Qué sucede si mi programa no cabe totalmente en la RAM?

    – Geminis

    31 de julio de 2019 a las 18:51

avatar de usuario
Lixas

Nada, porque Python precompila su script en un archivo PYC y lo ejecuta.

Sin embargo, si ocurre algún tipo de excepción, puede obtener una explicación un poco engañosa, porque la línea X puede tener un código diferente al que tenía antes de iniciar el script.

  • No necesariamente en un archivo.

    – Ignacio Vázquez-Abrams

    14 de marzo de 2011 a las 9:50

  • Pero, ¿qué pasa si vuelve a iniciar mientras se ejecuta, cuando los nuevos archivos pyc sobrescriben los antiguos, eso causará problemas en el programa que ya se estaba ejecutando o no?

    – caviar desacelerado

    3 de mayo de 2012 a las 1:31

  • No pasa nada. También lo comprobé en una pequeña prueba. Lo que sucede: el pyc es solo el compilado. Y esta compilación se carga en la RAM y luego se ejecuta. Por lo tanto, siempre es posible cambiar el programa, recompilar y ejecutar otra instancia, por ejemplo, en una consola diferente.

    – Chris

    7 de noviembre de 2014 a las 12:28

  • @Chris Inicié una instancia de mi script de python en una consola. Mientras se ejecutaba, cambié dos líneas de código e inicié otra instancia en una consola separada. Después de un tiempo, recibí un error de la primera consola sobre las dos líneas de código que cambié después de iniciarlo. por favor ayuda

    – doble_j

    26 de enero de 2015 a las 19:44

  • @Chris Creo que sé lo que sucede aquí. Si modifica un script y lo guarda mientras se está ejecutando, y la versión anterior presenta errores, en la lectura de seguimiento, se abre la versión actual del archivo y hace que el seguimiento tenga un aspecto diferente al que tenía cuando comenzó. Yo mismo he visto esto en varias ocasiones.

    – doble_j

    9 jun 2016 a las 17:41

avatar de usuario
Nearoo

Cuando ejecutas un programa en python y se inicia el intérprete, lo primero que sucede es lo siguiente:

  • el módulo sys y builtins se inicializa
  • la __main__ se inicializa el módulo, que es el archivo que le diste como argumento al intérprete; esto hace que su código se ejecute

Cuando se inicializa un módulo, se ejecuta su código, definiendo clases, variables y funciones en el proceso. El primer paso de su módulo (es decir, el archivo principal) probablemente será importar otros módulos, que nuevamente se inicializarán de la misma manera; sus espacios de nombres resultantes quedan disponibles para que los use su módulo. El resultado de un proceso de importación es en parte un objeto de módulo (python-) en la memoria. Este objeto tiene campos que apuntan a .py y .pyc contenido, pero estos ya no se evalúan: los objetos del módulo se almacenan en caché y su fuente nunca se ejecuta dos veces. Por eso, modificar el módulo después en el disco no tiene ningún efecto sobre la ejecución. Puede tener un efecto cuando la fuente se lee con fines introspectivos, como cuando se lanzan excepciones, o a través del módulo. inspeccionar.

Por eso el cheque if __name__ == "__main__" es necesario cuando se agrega código que no está diseñado para ejecutarse cuando se importa el módulo. Ejecutar el archivo como principal es equivalente a importar ese archivo, con la excepción de __name__ teniendo un valor diferente.


Fuentes:

avatar de usuario
buey

Esta es una pregunta divertida. La respuesta es que depende”.

Considere el siguiente código:

"Example script showing bad things you can do with python."

import os

print('this is a good script')
with open(__file__, 'w') as fdesc:
    fdesc.write('print("this is a bad script")')

import bad

Intente guardar lo anterior como “/tmp/bad.py”, luego haga “cd /tmp” y finalmente “python3 bad.py” y vea qué sucede.

En mi sistema ubuntu 20 veo el resultado:

this is a good script
this is a bad script

De nuevo, la respuesta a tu pregunta es “depende”. Si no hace nada funky, entonces el guión está en la memoria y está bien. Pero python es un lenguaje bastante dinámico, por lo que hay una variedad de formas de modificar su “script” y hacer que afecte la salida.

Si no está tratando de hacer nada extraño, entonces probablemente una de las cosas a tener en cuenta son las funciones internas de importación.

A continuación se muestra otro ejemplo que ilustra la idea (guarde como “/tmp/modify.py” y haga “cd /tmp” y luego “python3 modify.py” para ejecutar). los fiddle La función definida a continuación simula la modificación del script mientras se ejecuta (si lo desea, puede eliminar la función fiddle, colocar una time.sleep(300) en la penúltima línea y modifique el archivo usted mismo).

El caso es que desde la show función está realizando una importación dentro de la función en lugar de en la parte superior del módulo, la importación no se realizará hasta que se llame a la función. Si ha modificado el script antes de llamar showentonces se usará su versión modificada del script.

Si ve un comportamiento sorprendente o inesperado al modificar un script en ejecución, le sugiero que busque instrucciones de importación dentro de las funciones. A veces hay buenas razones para hacer ese tipo de cosas, por lo que lo verá en el código de las personas, así como en algunas bibliotecas de vez en cuando.

A continuación se muestra la demostración de cómo una importación dentro de una función puede causar efectos extraños. Puede probar esto tal como está en lugar de comentar la llamada al fiddle función para ver el efecto de modificar un script mientras se está ejecutando.

"Example showing import in a function"

import time

def yell(msg):
    "Yell a msg"
    return f'#{msg}#'
    
def show(msg):
    "Print a message nicely"
    import modify
    print(modify.yell(msg))

def fiddle():
    orig = open(__file__).read()
    with open(__file__, 'w') as fdesc:
        modified = orig.replace('{' + 'msg' + '}', '{msg.upper()}')
        fdesc.write(modified)

fiddle()        
show('What do you think?')

No, el resultado no reflejará los cambios una vez guardados. El resultado no cambiará cuando se ejecuten archivos de python normales. Tendrá que guardar sus cambios y volver a ejecutar su programa.

avatar de usuario
ITR

Si ejecuta el siguiente script:

from time import sleep

print("Printing hello world in: ")
for i in range(10, 0, -1):
    print(f"{i}...")
    sleep(1)
    
print("Hello World!")

Luego cambie “¡Hola mundo!” a “¡Hola StackOverflow!” mientras está en cuenta regresiva, seguirá emitiendo “Hello World”.

  • Como está escrito actualmente, su respuesta no está clara. Edite para agregar detalles adicionales que ayudarán a otros a comprender cómo esto aborda la pregunta formulada. Puede encontrar más información sobre cómo escribir buenas respuestas en el centro de ayuda.

    – Comunidad
    Bot

    25 de noviembre de 2021 a las 10:42

  • ¿Perdóneme? ¿Cómo es esto poco claro o digno de un voto negativo en lo más mínimo? Proporciona un ejemplo de “un script de python que tardará mucho tiempo en ejecutarse” y explica lo que sucederá.

    – RTI

    13 de diciembre de 2021 a las 11:03

avatar de usuario
pbacterio

No pasa nada. Una vez que el script se carga en la memoria y se ejecuta, se mantendrá así.

Una función de “recarga automática” se puede implementar de todos modos en su código, como lo hacen Flask y otros marcos.

  • Como está escrito actualmente, su respuesta no está clara. Edite para agregar detalles adicionales que ayudarán a otros a comprender cómo esto aborda la pregunta formulada. Puede encontrar más información sobre cómo escribir buenas respuestas en el centro de ayuda.

    – Comunidad
    Bot

    25 de noviembre de 2021 a las 10:42

  • ¿Perdóneme? ¿Cómo es esto poco claro o digno de un voto negativo en lo más mínimo? Proporciona un ejemplo de “un script de python que tardará mucho tiempo en ejecutarse” y explica lo que sucederá.

    – RTI

    13 de diciembre de 2021 a las 11:03

avatar de usuario
Yan Rey Yin

Esto es ligeramente diferente de lo que describe en su pregunta, pero funciona:

my_string = "Hello World!"

line = input(">>> ")
exec(line)

print(my_string)

Prueba de funcionamiento:

>>> print("Hey")
Hey
Hello World!

>>> my_string = "Goodbye, World"
Goodbye, World

Mira, puedes cambiar el comportamiento de tu código “cargado” dinámicamente.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad