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

È stato utile?

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top