2017-05-22 6 views
0

J'ai un morceau de code stocké dans une chaîne (l'utilisateur modifie cela dans une zone de texte dans mon application). Dans ce code, il existe une fonction que je veux exécuter plus tard en utilisant multiprocess.Pool. Mais cela ne fonctionne pas si les fonctions définies dans la chaîne sont imbriquées.multiprocess ne fonctionne pas bien avec des fonctions imbriquées dans certains cas

Notez que j'utilise multiprocess, plutôt que la norme multiprocessing, qui ne serait pas capable d'exécuter les fonctions définies dans la chaîne.

Voir les commentaires dans l'extrait de code suivant pour voir ce qui se passe. Y a-t-il une solution de contournement que je pourrais utiliser dans mon scénario?

funcs = """ 
def func(x): 
    return func_inner(x) + 1 

def func_inner(x): 
    return x + 1 
""" 

import multiprocess 

if __name__ == "__main__": 
    symbols = dict() 
    exec(funcs, symbols) 
    func = symbols["func"] 
    print(func(1)) # this is evaluated correctly as 3 so nesting functions work fine! 
    data = [1, 2, 3] 
    pool = multiprocess.Pool() 
    print(pool.map(func, data)) # this fails with NameError: name 'func_inner' is not defined! 

J'ai également essayé sur Windows et Linux. Ma version multiprocess est 0.70.5 et Python 3.5.

Répondre

0

Semble vous manque juste compile() pour votre fonction à base de chaîne:

funcs=compile(""" 
def func(x): 
    return func_inner(x) + 1 

def func_inner(x): 
    return x + 1 
""", '<string>', 'exec') 

if __name__ == "__main__": 
    import multiprocess 

    symbols = dict() 
    exec(funcs, symbols) 
    func = symbols["func"] 
    print(func(1)) 
    data = [1, 2, 3] 
    pool = multiprocess.Pool() 
    print(pool.map(func, data)) 

sorties pour moi: [3, 4, 5]

MISE À JOUR: ma version multiprocessus est - 0.70.4 essayer le correctif sale suivant, devrait travailler pour vous:

import multiprocess 

code_globals = {} 
code_locals = {} 
exec funcs in code_globals, code_locals 
print code_locals 
# {'func_inner': <function func_inner at 0x10aa607d0>, 'func': <function func at 0x10a97dde8>} 

code_globals['func_inner']=code_locals['func_inner'] 

print code_globals['func_inner'] 
#<function func_inner at 0x10a1427d0> 

func = code_locals['func'] 
print(func(1)) 
data = [1, 2, 3] 
pool = multiprocess.Pool() 
print(pool.map(func, data)) 
+0

Je crains qu'il ne reste pour moi avec la même erreur que précédemment. –

+0

Quelle version 'multiprocess' avez-vous? Je soupçonne que certaines choses se sont cassées dans les versions récentes. –

+0

Je peux confirmer qu'après avoir ajouté 'code_globals ['func_inner'] = code_locals ['func_inner']', l'extrait de code fonctionne. Mais le problème est que dans la vie réelle cela ne peut pas être utilisé parce que je ne sais pas à l'avance, quelle fonction sera appelée par le pool, qui est imbriqué, etc. J'aurais besoin de quelque chose comme 'code_globals.update (code_locals)' tous les symboles locaux aux symboles globaux. Mais avec cette ligne, l'échantillon se casse à nouveau. –