2017-12-30 10 views
0

Unten ist mein paralleler Code mit Multiprocessing-Modul Pool. Hier ist Parameter d ein Tupel, dessen Wortnummer eine Ganzzahl und Wort_zahl ein Dokument ist.python multiprocessing cPickle.PicklingError

def perDoc(d): 
    score = 0.0 
    word_count = d.word_count 
    word_number = d.word_number 
    for i, word in enumerate(q): 
     if word not in corpus_query_min: 
      continue 
     if word not in word_count: 
      frequency = 0 
     else: 
      frequency = word_count.get(word) 
     score += np.log(np.float(frequency + miu * corpus_word_count[i]/corpus_number)/ 
        (word_number + miu)) 
    #loglh[d.docID] = score 
if __name__ == '__main__': 
    pool = Pool(4) 
    pool.map(perDoc, doc_query_list) 
    pool.close() 

bekam ich den Fehler wie folgt aus:

cPickle.PicklingError: Can't pickle <class '__main__.doc_'>: attribute lookup __main__.doc_ failed 

Ist dies das Problem meiner Parameter d ein Tupel mit Dokument ist?

+0

Ihr Problem bezieht sich auf den Inhalt von 'doc_query_list', aber Sie haben den Code, der es erstellt, nicht zur Verfügung gestellt. Bitte geben Sie [MCVE] an, wenn Sie Hilfe benötigen. – ShadowRanger

+0

Es tut mir leid, dass ich diesen Teil vergessen habe. Im Folgenden ist doc_tuple ein 'collections.namedtuple'. \t 'doc_query_list.append (doc_tuple (d.docID, doc_temp, d.word_number))' –

+0

@ Yangyang.Guo. Aber welche Art von Objekt ist ein 'Dokument'? Zeigen Sie die Definition des namedtuple und aller darin enthaltenen Objekte an. – ekhumoro

Antwort

1

Psychic Debuggen, da Sie weitere Informationen (aber immer noch kein MCVE) gab:

Sie erstellt doc_tuple ‚s-Klasse mit:

doc_tuple = collections.namedtuple('doc_', ... attributes here ...) 

Die Diskrepanz zwischen dem string name übergeben ('doc_') und der Name, dem es zugewiesen wurde (doc_tuple), verursacht dieses Problem; Die beiden Namen müssen übereinstimmen, damit Instanzen der namedtuple pickleable sein können. Ändern Sie ihn auf:

# Binding matches name passed to namedtuple constructor now 
doc_tuple = collections.namedtuple('doc_tuple', ... attributes here ...) 

und stellen Sie sicher, dass es auf der obersten Ebene des Moduls definiert ist (nicht innerhalb einer anderen Klasse oder Funktion), und es sollte funktionieren.

+0

Ja! Das hat mein Problem richtig gelöst. Ohne Multiprocessing kann der Code jedoch ausgeführt werden. Nur ein bisschen neugierig. –

+0

@ Yangyang.Guo: 'Multiprocessing 'muss die Funktion, Argumente und Rückgabewerte jedes Worker-Task-Aufrufs serialisieren, und Sie tun dies über das Beizen. Ohne "Multiprocessing" werden die Daten niemals serialisiert, aber es ist immer noch falsch, die fehlende Übereinstimmung in der Bindung und dem bereitgestellten Namen zu haben, da dies alle anderen Anwendungen des Beizens verhindert, die "Repr" der Instanzen durcheinander bringt usw. – ShadowRanger