Преобразование типа встроенной функции в тип метода (в Python 3)

Рассмотрим простую функцию, например

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)

. Есть ли более эффективный способ сделать это?

16
задан JBernardo 24 May 2012 в 16:40
поделиться