Categorías
Python

Entrevista con Corey comunidad Python Schafer

 

Tabla de Contenidos

  • Adición de un sueño Python () con time.sleep ()
  • Adición de un sueño Python () con decoradores
  • Adición de un sueño Python () con ThreadsUsing time.sleep () El uso de eventos. wait ()
  • Usando time.sleep ()
  • Usando Event.wait ()
  • Adición de un sueño Python () con asíncrono IO
  • Adición de un sueño Python () con GUIsSleeping en TkinterSleeping en wxPython
  • dormir en tkinter
  • dormir en wxPython
  • Conclusión
  • Usando time.sleep ()
  • Usando Event.wait ()
  • dormir en tkinter
  • dormir en wxPython

¿Has necesitado para hacer su espera programa de Python para algo? La mayoría de las veces, te gustaría su código para ejecutar lo más rápido posible. Pero hay veces en que dejar que su sueño de código por un tiempo en realidad es en su mejor interés.

Por ejemplo, es posible utilizar un sueño Python () llamada para simular un retraso en su programa. Tal vez usted tiene que esperar a un archivo de carga o descarga, o para un gráfico para carga o ser atraídos por la pantalla. Incluso puede ser que tenga que hacer una pausa entre llamadas a una API web, o entre las consultas a una base de datos. La adición de sueño Python () llamadas a su programa puede ayudar en cada uno de estos casos, y muchos más!

En este tutorial, aprenderá cómo agregar el sueño Python () llama con:

  • time.sleep ()
  • decoradores
  • Hilos
  • asíncrono IO
  • interfaces gráficas de usuario

este artículo está destinado a desarrolladores intermedios que buscan hacer crecer su conocimiento de Python. Si esto suena como usted, entonces vamos a empezar! Bono

gratuito: Consigue nuestro «El poder de Python decoradores» guía gratuita que te muestra 3 patrones y técnicas avanzadas decorador se puede utilizar para escribir a más limpio y más programas Pythonic.

Adición de un sueño Python () con time.sleep ()

Python ha incorporado soporte para poner su programa de sueño. El módulo tiene un tiempo de sueño () la función que se puede utilizar para suspender la ejecución de la rosca pidiendo sin embargo muchos segundos que especifique.

Aquí está un ejemplo de cómo utilizar time.sleep ():

>>> import time
>>> time.sleep(3) # Sleep for 3 seconds

Si ejecuta este código en tu consola, entonces usted debe experimentar un retraso antes de que pueda entrar en una nueva declaración en el REPL.

Nota: En Python 3.5, los desarrolladores del núcleo cambia el comportamiento de time.sleep () ligeramente. La llamada al sistema nuevo sueño Python () tendrá una duración de, al menos, el número de segundos que ha especificado, incluso si el sueño es interrumpido por una señal. Esto no se aplica si la señal en sí genera una excepción, sin embargo.

Puede comprobar el tiempo que el sueño dura mediante el uso del módulo de Python timeit:

$ python3 -m timeit -n 3 "import time; time.sleep(3)"
3 loops, best of 3: 3 sec per loop

Aquí, se ejecuta el módulo de timeit con el parámetro -n, que dice timeit cuántas veces debe ejecutar la instrucción que sigue. Se puede ver que timeit corrió el estado 3 veces y que el mejor tiempo de ejecución fue de 3 segundos, que es lo que se esperaba.

El número predeterminado de veces que timeit se ejecutará el código es de un millón. Si se va a ejecutar el código anterior con el grupo -N defecto, a continuación, a los 3 segundos por iteración, su terminal colgaría durante aproximadamente 34 días! El módulo timeit tiene varias otras opciones de línea de comandos que se pueden extraer en su documentación.

Vamos a crear algo un poco más realista. Un administrador del sistema tiene que saber cuando uno de sus sitios web va hacia abajo. ¿Quieres ser capaz de verificar el código de estado de la página web con regularidad, pero no se puede consultar al servidor web constantemente o afectará el rendimiento. Una manera de hacer esta comprobación es utilizar una llamada al sistema Python sueño ():

import time
import urllib.request
import urllib.error

def uptime_bot(url):
while True:
try:
conn = urllib.request.urlopen(url)
except urllib.error.HTTPError as e:
# Email admin / log
print(f'HTTPError: {e.code} for {url}')
except urllib.error.URLError as e:
# Email admin / log
print(f'URLError: {e.code} for {url}')
else:
# Website is up
print(f'{url} is up')
time.sleep(60)

if __name__ == '__main__':
url = 'http://www.google.com/py'
uptime_bot(url)

Aquí se crean uptime_bot (), que toma una URL como argumento. La función entonces los intentos de abrir esa URL con urllib. Si hay una HTTPError o URLError, entonces el programa coge y lo imprime el error. (En un entorno real, que le registrar el error y, probablemente, envía un correo electrónico al webmaster o administrador del sistema.)

Si no se producen errores, a continuación, sus impresiones de código que todo está bien. Pase lo que pase, el programa va a dormir durante 60 segundos. Esto significa que sólo accede a la página web de una vez por minuto. La URL utilizada en este ejemplo es malo, por lo que la siguiente salida a la consola una vez por minuto:

HTTPError: 404 for http://www.google.com/py

Vaya por delante y actualizar el código para utilizar una buena URL conocido, como http://www.google.com. A continuación, puede volver a ejecutarlo para ver que funcione correctamente. También puede tratar de actualizar el código para enviar un correo electrónico o registrar los errores. Para obtener más información sobre cómo hacer esto, echa un vistazo a Envío de correos electrónicos con Python y registro en Python.

Adición de un sueño Python () con decoradores

Hay momentos en que necesita para volver a intentar una función que ha fallado. Un caso de uso popular para esto es cuando se necesita para volver a intentar una descarga de archivos porque el servidor estaba ocupado. Por lo general, no va a querer hacer una petición al servidor con demasiada frecuencia, por lo que la adición de un sueño Python () llamada entre cada solicitud es deseable.

Otro caso de uso que he experimentado personalmente es donde tengo que comprobar el estado de una interfaz de usuario durante una prueba automatizada. La interfaz de usuario podría cargar más rápido o más lento de lo habitual, dependiendo del ordenador que estoy corriendo la prueba sucesivamente. Esto puede cambiar lo que está en la pantalla en el momento en que mi programa es verificar algo.

En este caso, puede indicar al programa a dormir por un momento y luego vuelva a comprobar las cosas un par de segundos más tarde. Esto puede significar la diferencia entre una prueba y no pasa.

Puede utilizar un decorador añadir una llamada al sistema Python sueño () en cualquiera de estos casos. Si no está familiarizado con decorador s, o si desea dar un repaso a ellos, entonces echa un vistazo cartilla en Python decoradores. Echemos un vistazo a un ejemplo:

import time
import urllib.request
import urllib.error

def sleep(timeout, retry=3):
def the_real_decorator(function):
def wrapper(*args, **kwargs):
retries = 0
while retries < retry: try: value = function(*args, **kwargs) if value is None: return except: print(f'Sleeping for {timeout} seconds') time.sleep(timeout) retries += 1 return wrapper return the_real_decorator

sueño () es su decorador. Se acepta un valor de tiempo de espera y el número de veces que debe volver a intentar, que de forma predeterminada 3. En el interior del sueño () es otra función, the_real_decorator (), que acepta la función decorada.

Finalmente, la envoltura más interna función () acepta los argumentos y argumentos clave que se pasa a la función decorada. Aquí es donde sucede la magia! Se utiliza un bucle while para volver a intentar llamar a la función. Si hay una excepción, a continuación, se llama a time.sleep (), incrementar el contador de reintentos, e intente ejecutar de nuevo la función.

Ahora uptime_bot reescritura () para usar su nuevo decorador:

@sleep(3)
def uptime_bot(url):
try:
conn = urllib.request.urlopen(url)
except urllib.error.HTTPError as e:
# Email admin / log
print(f'HTTPError: {e.code} for {url}')
# Re-raise the exception for the decorator
raise urllib.error.HTTPError
except urllib.error.URLError as e:
# Email admin / log
print(f'URLError: {e.code} for {url}')
# Re-raise the exception for the decorator
raise urllib.error.URLError
else:
# Website is up
print(f'{url} is up')

if __name__ == '__main__':
url = 'http://www.google.com/py'
uptime_bot(url)

Aquí, decorar uptime_bot () con un sueño () de 3 segundos. También ha quitado el original bucle while, así como la edad llamada al sueño (60). El decorador ahora se encarga de esto.

Otra modificación que hemos hecho es añadir un aumento en el interior de los bloques de manejo de excepciones. Esto es para que el decorador funcionará correctamente. Se podría escribir el decorador para manejar estos errores, pero ya que estas excepciones sólo se aplican a urllib, que puede ser mejor mantener el decorador de la manera que es. De esta manera, se trabajará con una amplia variedad de funciones.

Nota: Si desea poner al día el manejo en Python excepción, a continuación, echa un vistazo a excepciones Python: Una introducción.

Hay algunas mejoras que se podría hacer a su decorador. Si se queda sin reintentos y todavía no funciona, entonces usted podría tener que volver a subir el último error. El decorador también espere 3 segundos después del último fracaso, lo que podría ser algo que no quiere que suceda. No dude en probar estos como un ejercicio!

la adición de un sueño Python () con Hilos

También hay ocasiones en que es posible que desee agregar una llamada Python sueño () a un hilo . Tal vez se está ejecutando un script de migración contra una base de datos con millones de registros de producción. No lo hace quiere causar ningún tiempo de inactividad, pero también no quiere esperar más tiempo del necesario para terminar la migración, por lo que decide utilizar hilo s.

Nota: hilos son un método de hacer la concurrencia en Python. Puede ejecutar múltiples hilos a la vez para aumentar el rendimiento de la aplicación. Si no está familiarizado con las discusiones en Python, a continuación, echa un vistazo a una introducción a roscar en Python.

Para evitar que los clientes de notar cualquier tipo de desaceleración, cada hilo tiene que funcionar durante un corto período y luego el sueño. Hay dos maneras de hacer esto: inicio de

Let examinado time.sleep ().

Usando time.sleep ()

El Python forestales shows Cookbook un ejemplo agradable que los usos time.sleep (). módulo de registro de Python es seguro para subprocesos, por lo que es un poco más útil que la de impresión () declaraciones de este ejercicio. El siguiente código se basa en este ejemplo:

import logging
import threading
import time

def worker(arg):
while not arg["stop"]:
logging.debug("worker thread checking in")
time.sleep(1)

def main():
logging.basicConfig(
level=logging.DEBUG,
format="%(relativeCreated)6d %(threadName)s %(message)s"
)
info = {"stop": False}
thread = threading.Thread(target=worker, args=(info,))
thread_two = threading.Thread(target=worker, args=(info,))
thread.start()
thread_two.start()

while True:
try:
logging.debug("Checking in from main thread")
time.sleep(0.75)
except KeyboardInterrupt:
info["stop"] = True
logging.debug('Stopping')
break
thread.join()
thread_two.join()

if __name__ == "__main__":
main()

En este caso utilizará módulo threading de Python para crear dos hilos. También se crea un objeto de registro que registrará el threadName a la salida estándar. A continuación, se inicia ambos hilos e iniciar un bucle que entrar desde el hilo principal de vez en cuando. KeyboardInterrupt utiliza para atrapar el usuario pulsando Ctrl + C.

intente ejecutar el código anterior en su terminal. Debería ver una salida similar a la siguiente:

0 Thread-1 worker thread checking in
1 Thread-2 worker thread checking in
1 MainThread Checking in from main thread
752 MainThread Checking in from main thread
1001 Thread-1 worker thread checking in
1001 Thread-2 worker thread checking in
1502 MainThread Checking in from main thread
2003 Thread-1 worker thread checking in
2003 Thread-2 worker thread checking in
2253 MainThread Checking in from main thread
3005 Thread-1 worker thread checking in
3005 MainThread Checking in from main thread
3005 Thread-2 worker thread checking in

A medida que cada hilo de carreras y luego duerme, la salida de registro se imprime en la consola. Ahora que usted ha intentado un ejemplo, usted será capaz de utilizar estos conceptos en su propio código.

Usando Event.wait ()

El módulo threading proporciona un Evento () que se puede utilizar como time.sleep (). Sin embargo, Evento () tiene la ventaja añadida de ser más sensible. La razón de esto es que cuando se establece el evento, el programa se romperá fuera del circuito de inmediato. Con time.sleep (), el código tendrá que esperar a que la llamada Python sueño () hasta el final antes de que el hilo puede salir.

La razón por la que te gustaría usar wait () aquí es porque espera () es no bloquear , mientras que time.sleep () es bloqueo . Lo que esto significa es que cuando se utiliza time.sleep (), podrás bloquear el hilo principal de seguir funcionando mientras se espera a que el sueño () llamada al final. wait () resuelve este problema. Usted puede leer más acerca de cómo funciona todo esto en la documentación de enhebrado de Python.

Así es como se agrega una llamada Python sueño () con Event.wait ():

import logging
import threading

def worker(event):
while not event.isSet():
logging.debug("worker thread checking in")
event.wait(1)

def main():
logging.basicConfig(
level=logging.DEBUG,
format="%(relativeCreated)6d %(threadName)s %(message)s"
)
event = threading.Event()

thread = threading.Thread(target=worker, args=(event,))
thread_two = threading.Thread(target=worker, args=(event,))
thread.start()
thread_two.start()

while not event.isSet():
try:
logging.debug("Checking in from main thread")
event.wait(0.75)
except KeyboardInterrupt:
event.set()
break

if __name__ == "__main__":
main()

En este ejemplo, se crea threading.Event () y pasarlo al trabajador (). (Recordemos que en el ejemplo anterior, en su lugar pasó un diccionario.) A continuación, configurar sus bucles para comprobar si es o no de eventos se establece. Si no es así, entonces su código imprime un mensaje y espera un poco antes de comprobar de nuevo. Para establecer el evento, puede pulsar Ctrl + C. Una vez que se establece el evento, trabajador () devolverá y el bucle se romperá, terminando el programa.

Nota: Si desea aprender más acerca de los diccionarios, a continuación, echa un vistazo a Diccionarios en Python.

Tome una mirada más cercana en el bloque de código de seguridad. ¿Cómo se pasa en un momento diferente del sueño para cada subproceso de trabajo? Se puede averiguarlo? No dude en hacer frente a este ejercicio por su cuenta!

Adición de un sueño Python se añadieron () capacidades de llamada Con asíncrono IO

asíncronas a Python en la versión 3.4, y este conjunto de características ha sido agresivamente expandiendo desde entonces. asíncrono programación es un tipo de programación en paralelo que le permite ejecutar varias tareas a la vez. Cuando termina una tarea, se le notificará el hilo principal.

asyncio es un módulo que le permite agregar una llamada Python sueño () de forma asincrónica. Si no está familiarizado con la ejecución de la programación asíncrona de Python, entonces echa un vistazo asíncrono IO en Python: Un recorrido completo y Python concurrencia y programación paralela.

He aquí un ejemplo de la propia documentación de Python:

import asyncio

async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')

# Python 3.7+
asyncio.run(main())

En este ejemplo, la marcha principal () y tienen que dormir durante un segundo entre dos llamadas (impresión).

Aquí hay un ejemplo más convincente de la parte corrutinas y tareas de la documentación asyncio:

import asyncio
import time

async def output(sleep, text):
await asyncio.sleep(sleep)
print(text)

async def main():
print(f"Started: {time.strftime('%X')}")
await output(1, 'First')
await output(2, 'Second')
await output(3, 'Third')
print(f"Ended: {time.strftime('%X')}")

# Python 3.7+
asyncio.run(main())

En este código, se crea un trabajador llamado de salida () que toma en el número de segundos que el sueño y el texto a imprimir. A continuación, utiliza la palabra clave Await de Python que esperar a que el código de salida () para ejecutar. Aguarde se requiere aquí porque la salida () se ha marcado como una función asíncrona, por lo que no se puede llamar como lo haría con una función normal.

Cuando se ejecuta este código, el programa ejecutará aguardan 3 veces. El código esperará para 1, 2, y 3 segundos, durante un tiempo total de espera de 6 segundos. También puede volver a escribir el código para que las tareas se ejecutan en paralelo:

import asyncio
import time

async def output(text, sleep):
while sleep > 0:
await asyncio.sleep(1)
print(f'{text} counter: {sleep} seconds')
sleep -= 1

async def main():
task_1 = asyncio.create_task(output('First', 1))
task_2 = asyncio.create_task(output('Second', 2))
task_3 = asyncio.create_task(output('Third', 3))
print(f"Started: {time.strftime('%X')}")
await task_1
await task_2
await task_3
print(f"Ended: {time.strftime('%X')}")

if __name__ == '__main__':
asyncio.run(main())

Ahora se está utilizando el concepto de tareas , que usted puede hacer con create_task (). Cuando se utiliza tareas en asyncio, Python ejecutar las tareas de forma asíncrona. Por lo tanto, cuando se ejecuta el código anterior, se debe terminar en 3 segundos en total en lugar de 6.

Adición de un sueño Python () llamada Con aplicaciones GUI

de línea de comandos no son el único lugar donde es posible que tenga que añadir Python sleep () llamadas. Cuando se crea una interfaz de usuario (GUI) gráfica de usuario, podrás vez en cuando necesita añadir retrasos. Por ejemplo, puede crear una aplicación FTP para descargar millones de archivos, pero hay que añadir una llamada sleep () entre lotes para que no saturar el servidor. código

interfaz gráfica de usuario se ejecutará toda su procesamiento y elaboración de un hilo principal llamado el bucle de eventos . Si utiliza time.sleep () dentro del código de interfaz gráfica de usuario, entonces se bloqueará su caso bucle . Desde la perspectiva del usuario, la aplicación podría aparecer a congelar. El usuario no será capaz de interactuar con la aplicación mientras se está durmiendo con este método. (En Windows, puedes ser una alerta acerca de cómo su aplicación ya no responde.)

Afortunadamente, hay otros métodos que puede utilizar además time.sleep (). En las siguientes secciones, aprenderá cómo agregar el sueño Python () llamadas tanto en Tkinter y wxPython.

Dormir en Tkinter

tkinter es una parte de la biblioteca estándar de Python. Puede no estar disponible para usted si usted está utilizando una versión pre-instalada de Python en Linux o Mac. Si recibe un ImportError, entonces usted tiene que mirar en la forma de añadirlo a su sistema. Pero si instala Python sí mismo, entonces tkinter ya debería estar disponible.

Vamos a empezar por mirar un ejemplo que usa time.sleep (). Ejecutar este código para ver lo que sucede cuando se agrega un sueño Python () llamar por el camino equivocado:

import tkinter
import time

class MyApp:
def __init__(self, parent):
self.root = parent
self.root.geometry("400x400")
self.frame = tkinter.Frame(parent)
self.frame.pack()
b = tkinter.Button(text="click me", command=self.delayed)
b.pack()

def delayed(self):
time.sleep(3)

if __name__ == "__main__":
root = tkinter.Tk()
app = MyApp(root)
root.mainloop()

Una vez que haya ejecutado el código, pulsa el botón en su interfaz gráfica de usuario. El botón se pegue durante tres segundos, ya que espera para el sueño () a fin. Si la aplicación tiene otros botones, entonces no sería capaz de hacer clic en ellos. Usted no puede cerrar la aplicación mientras se está durmiendo, o bien, ya que no puede responder al evento de cierre.

Para obtener tkinter a dormir adecuadamente, tendrá que usar después de ():

import tkinter

class MyApp:
def __init__(self, parent):
self.root = parent
self.root.geometry("400x400")
self.frame = tkinter.Frame(parent)
self.frame.pack()
self.root.after(3000, self.delayed)

def delayed(self):
print('I was delayed')

if __name__ == "__main__":
root = tkinter.Tk()
app = MyApp(root)
root.mainloop()

Aquí crear una aplicación que es de 400 píxeles de ancho por 400 píxeles de alto. No tiene widgets en ella. Todo lo que hará es mostrar un marco. A continuación, se llama a self.root.after (), donde self.root es una referencia al objeto de Tk (). después () toma dos argumentos:

En este caso, la aplicación va a imprimir una cadena a la salida estándar después de 3 segundos. Se puede pensar en después () como el tkinter versión de time.sleep (), sino que también añade la posibilidad de llamar a una función después de que el sueño ha terminado.

Se podría utilizar esta funcionalidad para mejorar la experiencia del usuario. Mediante la adición de una llamada Python sueño (), puede hacer que la aplicación aparezca para cargar más rápido y luego iniciar un proceso de mayor duración después le toca. De esta manera, el usuario no tendrá que esperar a que la aplicación abierta.

Dormir en wxPython

Hay dos diferencias principales entre wxPython y Tkinter: Marco

El wxPython no está incluido en Python, por lo que tendrá que instalarlo usted mismo. Si no está familiarizado con wxPython, a continuación, echa un vistazo a cómo construir una aplicación con interfaz gráfica de Python Con wxPython.

En wxPython, puede utilizar wx.CallLater () para añadir una llamada Python sueño ():

import wx

class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='Hello World')
wx.CallLater(4000, self.delayed)
self.Show()

def delayed(self):
print('I was delayed')

if __name__ == '__main__':
app = wx.App()
frame = MyFrame()
app.MainLoop()

Aquí, subclase wx.Frame directamente y luego llamar wx.CallLater (). Esta función toma los mismos parámetros que Tkinter de después ():

Cuando se ejecuta este código, se debe ver una ventana pequeña en blanco aparecen sin ningún widget. Después de 4 segundos, verá la cadena 'que se retrasó' impresa en la salida estándar.

Uno de los beneficios de utilizar wx.CallLater () es que es seguro para subprocesos. Puede utilizar este método desde el interior de un hilo para llamar a una función que está en la aplicación principal wxPython.

Conclusión

Con este tutorial, que ha adquirido una valiosa nueva técnica para añadir a su caja de herramientas Python! Usted sabe cómo añadir retrasos a caminar de sus aplicaciones y les impide utilizar los recursos del sistema. Incluso puede utilizar el sueño Python () llamadas para ayudar a su código de interfaz gráfica de usuario vuelve a dibujar con mayor eficacia. Esto hará que la experiencia de usuario mucho mejor para sus clientes!

En resumen, usted ha aprendido a añadir el sueño Python () llama con las siguientes herramientas:

  • time.sleep ()
  • Decoradores
  • Hilos
  • asyncio
  • Tkinter
  • wxPython

Ahora puede tomar lo que has aprendido y empezar a poner su código a dormir!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *