2010-05-28 10 views
5

(Tenete a mente che sto lavorando in Python 3, quindi una soluzione ha bisogno di lavorare in Python 3.)Python: usando `copyreg` per definire riduttori per i tipi che hanno già riduttori

vorrei usare il modulo copyreg per insegnare a Python come decapare le funzioni. Quando ho provato a farlo, l'oggetto _Pickler proverebbe ancora a decapare le funzioni utilizzando la funzione save_global. (Che non funziona per i metodi non legato, e che è la motivazione per fare questo.)

Sembra _Pickler primi tentativi di guardare nel proprio dispatch per il tipo di oggetto che si desidera salamoia prima di guardare in copyreg.dispatch_table . Non sono sicuro che sia intenzionale.

C'è qualche modo per me di dire a Python di decapare le funzioni con il riduttore che fornisco?

risposta

1

Il seguente trucco sembra funzionare in Python 3.1 ...:

import copyreg 
def functionpickler(f): 
    print('pickling', f.__name__) 
    return f.__name__ 

ft = type(functionpickler) 
copyreg.pickle(ft, functionpickler) 

import pickle 
pickle.Pickler = pickle._Pickler 
del pickle.Pickler.dispatch[ft] 

s = pickle.dumps(functionpickler) 
print('Result is', s) 

Fuori di questo, le due linee hacker sono:

pickle.Pickler = pickle._Pickler 
del pickle.Pickler.dispatch[ft] 

È necessario rimuovere la voce dispatch per le funzioni 'digita perché altrimenti avanza la registrazione copyreg; e non penso che tu possa farlo sul Pickler con codice C, quindi devi impostarlo su quello con codice Python.

Sarebbe un po 'meno di un trucco per sottoclasse _Pickler con una classe di tuo, che fa la sua propria dispatch (la copia del genitore e la rimozione della voce per il tipo di funzione), e quindi utilizzare il sottoclasse specifica (e la sua metodo di dumping) anziché pickle.dump; tuttavia sarebbe anche un po 'meno conveniente che questo monkeypatching di pickle stesso.

+0

Nice hack. Ma voglio davvero godermi la velocità C di '_pickle' ... –