Uso dinamico di un metodo di classe definita in un modulo di estensione Cython
Domanda
Vorrei utilizzare l'implementazione C di un metodo di classe (generata da Cython ) se è attualmente, oppure utilizzare il suo equivalente pitone se l'estensione C non è presente. Ho provato questo:
class A(object):
try:
import c_ext
method = c_ext.optimized_method
except ImportError:
def method(self):
return "foo"
Dove optimized_method è una funzione definita in un Cython modulo:
def optimized_method(self):
return "fasterfoo"
Ma questo non funziona:
>>> A().method()
exceptions.TypeError: optimized_method() takes exactly one argument (0 given)
L'unico modo che ho trovato per fare questo lavoro è il seguente:
class A(object):
def method(self):
try:
import c_ext
return c_ext.optimized_method(self)
except ImportError:
pass
return "foo"
Ma il controllo per la presenza del modulo ad ogni chiamata di funzione sembra abbastanza non ottimale ... Perché il mio primo approccio non funziona?
[modifica]: aggiunto Cython del modulo contenuto
Soluzione
Ok ho appena trovato la risposta ...
Il problema deriva dal modo Cython avvolge le funzioni che le esportazioni : ogni metodo è non legato a prescindere dal punto in cui si fa riferimento
.La soluzione è quella di dichiarare in modo esplicito un metodo legato:
class A(object):
def method(self):
return "foo"
try:
import c_ext
import types
A.method = types.MethodType(c_ext.optimized_method, None, A)
except ImportError:
pass