Tengo un script de Python que a veces muestra imágenes al usuario. Las imágenes pueden, a veces, ser bastante grandes y se reutilizan con frecuencia. Mostrarlos no es crítico, pero mostrar el mensaje asociado a ellos es. Tengo una función que descarga la imagen necesaria y la guarda localmente. Ahora mismo se ejecuta en línea con el código que muestra un mensaje para el usuario, pero a veces puede tomar más de 10 segundos para las imágenes no locales. ¿Hay alguna manera de llamar a esta función cuando sea necesaria, pero ejecutarla en segundo plano mientras el código continúa ejecutándose? Solo usaría una imagen predeterminada hasta que esté disponible la correcta.función de fondo en Python
Respuesta
hacer algo como esto:
def function_that_downloads(my_args):
# do some long download here
continuación, en línea, hacer algo como esto:
import threading
def my_inline_function(some_args):
#do some stuff
download_thread = threading.Thread(target=function_that_downloads, args=my_args)
download_thread.start()
#continue doing stuff
es posible que desee comprobar si el mensaje ha terminado antes de pasar a otras cosas llamando download_thread.isAlive()
¡Agradable y simple! Gracias. – nicky
El intérprete permanece abierto hasta que se cierra el hilo. (ejemplo 'import threading, time; wait = lambda: time.sleep (2); t = threading.Thread (target = wait); t.start(); print ('end')'). Esperaba que también se desprendiera el "trasfondo". – ThorSummoner
@ThorSummoner Los hilos están contenidos dentro del mismo proceso. Si está buscando generar un nuevo proceso, en su lugar querrá examinar los módulos de python 'subprocess' o' multiprocessing'. – TorelTwiddler
Normalmente, la forma de hacer esto sería utilizar un conjunto de subprocesos y cola de descargas, que emitirían una señal, a.k.a un evento, esa tarea ha terminado de procesarse. Puede hacer esto dentro del alcance del que proporciona Python. Para realizar dichas acciones, usaría event objects y Queue module.
Sin embargo, una demostración rápida y sucia de lo que puede hacer uso de un simple threading.Thread
aplicación puede verse a continuación:
import os
import threading
import time
import urllib2
class ImageDownloader(threading.Thread):
def __init__(self, function_that_downloads):
threading.Thread.__init__(self)
self.runnable = function_that_downloads
self.daemon = True
def run(self):
self.runnable()
def downloads():
with open('somefile.html', 'w+') as f:
try:
f.write(urllib2.urlopen('http://google.com').read())
except urllib2.HTTPError:
f.write('sorry no dice')
print 'hi there user'
print 'how are you today?'
thread = ImageDownloader(downloads)
thread.start()
while not os.path.exists('somefile.html'):
print 'i am executing but the thread has started to download'
time.sleep(1)
print 'look ma, thread is not alive: ', thread.is_alive()
probablemente tendría sentido para no sondea que estoy haciendo anteriormente. En cuyo caso, me gustaría cambiar el código para esto:
import os
import threading
import time
import urllib2
class ImageDownloader(threading.Thread):
def __init__(self, function_that_downloads):
threading.Thread.__init__(self)
self.runnable = function_that_downloads
def run(self):
self.runnable()
def downloads():
with open('somefile.html', 'w+') as f:
try:
f.write(urllib2.urlopen('http://google.com').read())
except urllib2.HTTPError:
f.write('sorry no dice')
print 'hi there user'
print 'how are you today?'
thread = ImageDownloader(downloads)
thread.start()
# show message
thread.join()
# display image
en cuenta que no hay bandera demonio establecido aquí.
Prefiero usar gevent para este tipo de cosas:
import gevent
from gevent import monkey; monkey.patch_all()
greenlet = gevent.spawn(function_to_download_image)
display_message()
# ... perhaps interaction with the user here
# this will wait for the operation to complete (optional)
greenlet.join()
# alternatively if the image display is no longer important, this will abort it:
#greenlet.kill()
Todo se ejecuta en un hilo, pero cada vez que se bloquea una operación del kernel, gevent cambia de contexto cuando hay otros "greenlets" en ejecución. Las preocupaciones sobre el bloqueo, etc. son muy reducidas, ya que solo hay una cosa por vez, pero la imagen continuará descargando cada vez que se ejecute una operación de bloqueo en el contexto "principal".
Según la cantidad y el tipo de cosas que desee hacer en segundo plano, esto puede ser mejor o peor que las soluciones basadas en subprocesos; sin duda, es mucho más escalable (es decir, puede hacer muchas más cosas en segundo plano), pero eso podría no ser preocupante en la situación actual.
- 1. Color de fondo para Tk en Python
- 2. Procesos de fondo asincrónicos en Python?
- 3. función url() para fondo HTML
- 4. función anidada en Python
- 5. función raw_input en Python
- 6. Función super() de Python
- 7. función ".format" de python
- 8. Función de rango Python
- 9. Biblioteca de cliente de Selenium-Python - Automatización en el fondo
- 10. Python/wxPython: haciendo el trabajo continuamente en el fondo
- 11. llamada función anidada en Python
- 12. Pointfree combinación función en Python
- 13. función gamma incompleta en python?
- 14. función de impresión python en tiempo real
- 15. ¿Miembro estático de una función en Python?
- 16. Función de estilo Clojure "subprocesamiento" en Python
- 17. Establecer firma de función en Python
- 18. error de función no definida en Python
- 19. Evitar anulación de función en Python
- 20. función de estilo MATLAB find() en Python
- 21. Función de cifrado César en Python
- 22. Cambiando una implementación de función en Python
- 23. Función de declaración al final del archivo en Python
- 24. Python composición de la función
- 25. Python socket.sendall() función
- 26. Parámetros de la función - Python
- 27. Python - Pasar una función a otra función
- 28. python: función slow timeit()
- 29. Python, función opuesta urllib.urlencode
- 30. Python función anidada alcances
¿qué versión de python? –