Vorrei utilizzare un decoratore su una funzione che successivamente passerò a un pool di multiprocessing. Tuttavia, il codice non funziona con "PicklingError: Can pickle: lookup degli attributi __builtin__
.function failed". Non vedo proprio perché fallisce qui. Sono certo che sia qualcosa di semplice, ma non riesco a trovarlo. Di seguito è riportato un esempio "funzionante" minimo. Pensavo che usare la funzione functools
sarebbe stato sufficiente per far funzionare tutto questo.Decoratore Python con multielaborazione fallita
Se commento la decorazione della funzione, funziona senza problemi. Di cosa si tratta multiprocessing
che sto fraintendendo qui? C'è un modo per farlo funzionare?
Edit: Dopo l'aggiunta sia di una classe decoratrice callable e una funzione decoratore, si scopre che la funzione decoratore funziona come previsto. Il decoratore di classi chiamabili continua a fallire. Di cosa si tratta nella versione della classe chiamabile che impedisce che venga decapata?
import random
import multiprocessing
import functools
class my_decorator_class(object):
def __init__(self, target):
self.target = target
try:
functools.update_wrapper(self, target)
except:
pass
def __call__(self, elements):
f = []
for element in elements:
f.append(self.target([element])[0])
return f
def my_decorator_function(target):
@functools.wraps(target)
def inner(elements):
f = []
for element in elements:
f.append(target([element])[0])
return f
return inner
@my_decorator_function
def my_func(elements):
f = []
for element in elements:
f.append(sum(element))
return f
if __name__ == '__main__':
elements = [[random.randint(0, 9) for _ in range(5)] for _ in range(10)]
pool = multiprocessing.Pool(processes=4)
results = [pool.apply_async(my_func, ([e],)) for e in elements]
pool.close()
f = [r.get()[0] for r in results]
print(f)
Questo post sembra indicare che il decapaggio degli oggetti decorati è complicato: http://gael-varoquaux.info/blog/?p = 120 – Daenyth
Sì, ho trovato anche quella pagina. Ecco perché ho aggiunto il wrapper 'functools'. Ma non sembra fare alcuna differenza. Confesso di non capire veramente cosa sta succedendo sotto per vedere perché fallisce. – agarrett