2009-04-07 8 views
3

Ich mag würde die C Implementierung einer Klasse-Methode verwenden (erzeugt aus Cython), falls es vorhanden ist, oder dessen Python äquivalent verwenden, wenn die C-Erweiterung nicht vorhanden ist. Ich versuchte zunächst, dies:Dynamische Verwendung einer Klassenmethode in einer Modul Cython Erweiterung definiert

class A(object): 
    try: 
     import c_ext 
     method = c_ext.optimized_method 
    except ImportError: 
     def method(self): 
      return "foo" 

Wo optimized_method eine Funktion in einem Cython Modul definiert ist:

def optimized_method(self): 
    return "fasterfoo" 

Aber das funktioniert nicht:

>>> A().method() 
exceptions.TypeError: optimized_method() takes exactly one argument (0 given) 

Die einzige Art, wie ich gefunden Machen Sie diese Arbeit ist:

class A(object): 
    def method(self): 
     try: 
      import c_ext 
      return c_ext.optimized_method(self) 
     except ImportError: 
      pass 
     return "foo" 

Die Überprüfung der Anwesenheit des Moduls bei jedem Funktionsaufruf scheint jedoch ziemlich suboptimal zu sein ... Warum funktioniert mein erster Ansatz nicht?

[Bearbeiten]: hinzugefügt Cython Moduls Inhalt

+0

Ich würde vorschlagen, dass Sie zeigen, wie c_ext.optimized_method aus Gründen der Klarheit definiert wurde – Moe

Antwort

4

Ok Ich habe gerade die Antwort ...

Das Problem kommt aus dem Weg Cython wraps the functions it exports: jede Methode ungebunden ist, unabhängig von wo aus sie verwiesen wird.

ist die Lösung explizit eine gebundene Methode zu deklarieren:

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