Рассмотрим простую функцию типа
def increment(self):
self.count += 1
который запускается через Cython и скомпилирован в модуль расширения. Предположим, теперь я хотел бы сделать эту функцию методом для класса. Например:
class Counter:
def __init__(self):
self.count = 0
from compiled_extension import increment
Counter.increment = increment
Теперь это не сработает, поскольку соглашение о вызове на уровне C будет нарушено. Например:
>>> c = Counter()
>>> c.increment()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: increment() takes exactly one argument (0 given)
Но в Python 2 мы можем преобразовать функцию в несвязанный метод, выполнив:
Counter.increment = types.MethodType(increment, None, Counter)
Как я могу выполнить эту же задачу в Python 3?
Один простой способ - использовать тонкую оболочку:
from functools import wraps
def method_wraper(f):
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
return wraps(f)(wrapper)
Counter.increment = method_wrapper(increment)
Есть ли более эффективный способ сделать это?