Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

223
Vistas
Aplicar un método a una lista de objetos en paralelo usando multiprocesamiento

He creado una clase con varios métodos. Uno de los métodos consume mucho tiempo, my_process , y me gustaría hacer ese método en paralelo. Me encontré con Python Multiprocesamiento: aplique el método de clase a una lista de objetos, pero no estoy seguro de cómo aplicarlo a mi problema y qué efecto tendrá en los otros métodos de mi clase.

 class MyClass(): def __init__(self, input): self.input = input self.result = int def my_process(self, multiply_by, add_to): self.result = self.input * multiply_by self._my_sub_process(add_to) return self.result def _my_sub_process(self, add_to): self.result += add_to list_of_numbers = range(0, 5) list_of_objects = [MyClass(i) for i in list_of_numbers] list_of_results = [obj.my_process(100, 1) for obj in list_of_objects] # multi-process this for-loop print list_of_numbers print list_of_results [0, 1, 2, 3, 4] [1, 101, 201, 301, 401]
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Voy a ir contra la corriente aquí, y sugiero ceñirme a lo más simple que pueda funcionar ;-) Es decir, las funciones tipo Pool.map() son ideales para esto, pero están restringidas a pasar un solo argumento. En lugar de hacer esfuerzos heroicos para evitar eso, simplemente escriba una función auxiliar que solo necesite un único argumento: una tupla. Entonces todo es fácil y claro.

Aquí hay un programa completo que adopta ese enfoque, que imprime lo que desea en Python 2 e independientemente del sistema operativo:

 class MyClass(): def __init__(self, input): self.input = input self.result = int def my_process(self, multiply_by, add_to): self.result = self.input * multiply_by self._my_sub_process(add_to) return self.result def _my_sub_process(self, add_to): self.result += add_to import multiprocessing as mp NUM_CORE = 4 # set to the number of cores you want to use def worker(arg): obj, m, a = arg return obj.my_process(m, a) if __name__ == "__main__": list_of_numbers = range(0, 5) list_of_objects = [MyClass(i) for i in list_of_numbers] pool = mp.Pool(NUM_CORE) list_of_results = pool.map(worker, ((obj, 100, 1) for obj in list_of_objects)) pool.close() pool.join() print list_of_numbers print list_of_results

Un gran de magia

Debo señalar que hay muchas ventajas al adoptar el enfoque muy simple que sugiero. Más allá de eso, "simplemente funciona" en Pythons 2 y 3, no requiere cambios en sus clases y es fácil de entender, también funciona bien con todos los métodos de Pool .

Sin embargo, si tiene varios métodos que desea ejecutar en paralelo, puede ser un poco molesto escribir una pequeña función de trabajo para cada uno. Así que aquí hay un poco de "magia" para solucionar eso. Cambiar worker() así:

 def worker(arg): obj, methname = arg[:2] return getattr(obj, methname)(*arg[2:])

Ahora, una sola función de trabajador es suficiente para cualquier cantidad de métodos, con cualquier cantidad de argumentos. En su caso específico, simplemente cambie una línea para que coincida:

 list_of_results = pool.map(worker, ((obj, "my_process", 100, 1) for obj in list_of_objects))

Las generalizaciones más o menos obvias también pueden servir para métodos con argumentos de palabras clave. Pero, en la vida real, normalmente me atengo a la sugerencia original. En algún momento, satisfacer las generalizaciones hace más daño que bien. Por otra parte, me gustan las cosas obvias ;-)

over 4 years ago · Santiago Trujillo Denunciar

0

Si su clase no es "enorme", creo que la orientación al proceso es mejor. Se sugiere pool en multiprocesamiento.
Este es el tutorial -> https://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers

Luego add_to de my_process ya que son rápidos y puede esperar hasta el final del último proceso.

 def my_process(input, multiby): return xxxx def add_to(result,a_list): xxx p = Pool(5) res = [] for i in range(10): res.append(p.apply_async(my_process, (i,5))) p.join() # wait for the end of the last process for i in range(10): print res[i].get()
over 4 years ago · Santiago Trujillo Denunciar

0

Por lo general, la forma más fácil de ejecutar el mismo cálculo en paralelo es el método de map de un multiprocessing.Pool (o la función as_completed de concurrent.futures en Python 3).

Sin embargo, el método map aplica una función que solo toma un argumento para una iteración de datos usando múltiples procesos.

Entonces esta función no puede ser un método normal, porque requiere al menos dos argumentos; ¡también debe incluirse a self ! Sin embargo, podría ser un método estático. Consulte también esta respuesta para obtener una explicación más detallada.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda