2009-04-07 3 views
3

Je souhaite utiliser l'implémentation C d'une méthode de classe (générée à partir de Cython) si elle est présente, ou utiliser son équivalent Python si l'extension C n'est pas présente. J'ai d'abord essayé ceci:Utilisation dynamique d'une méthode de classe définie dans un module d'extension Cython

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

Où optimized_method est une fonction définie dans un module Cython:

def optimized_method(self): 
    return "fasterfoo" 

Mais cela ne fonctionne pas:

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

La seule manière que je trouvais à faire ce travail est:

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

Mais vérifier la présence du module à chaque appel de fonction semble tout à fait sous-optimal ... Pourquoi ma première approche ne fonctionne-t-elle pas?

[modifier]: ajout Cython contenu du module de

+0

Je suggère que vous montrer comment c_ext.optimized_method a été défini par souci de clarté – Moe

Répondre

4

Ok je viens de trouver la réponse ...

Le problème vient de la façon Cython wraps the functions it exports: chaque méthode est non liée indépendamment de l'endroit où il est référencé.

La solution est de déclarer explicitement une méthode liée:

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 
Questions connexes