Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

228
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!