Динамическое использование метода класса, определенного в модуле расширения Cython - PullRequest
3 голосов
/ 07 апреля 2009

Я хотел бы использовать реализацию C метода класса (генерируемого из Cython ), если он присутствует, или использовать его эквивалент Python, если расширение C отсутствует. Я впервые попробовал это:

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

Где optimized_method - это функция, определенная в модуле Cython :

def optimized_method(self):
    return "fasterfoo"

Но это не работает:

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

Единственный способ найти эту работу - это:

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

Но проверка присутствия модуля при каждом вызове функции кажется неоптимальной ... Почему мой первый подход не работает?

[править]: добавлено Cython содержимое модуля

1 Ответ

4 голосов
/ 07 апреля 2009

Хорошо, я только что нашел ответ ...

Проблема возникает из-за того, что Cython упаковывает экспортируемые им функции : каждый метод не связан, независимо от того, где на него ссылаются.

Решение состоит в том, чтобы явно объявить связанный метод:

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
...