Динамическое использование метода класса, определенного в модуле расширения Cython.

StackOverflow https://stackoverflow.com/questions/725777

  •  05-09-2019
  •  | 
  •  

Вопрос

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

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

Где оптимизированный_метод — это функция, определенная в Китон модуль:

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 оборачивает экспортируемые функции:каждый метод несвязан независимо от того, где на него ссылаются.

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

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top