@wrapt декораторы и исправления обезьян - PullRequest
0 голосов
/ 05 марта 2020

@ оберточное условное исправление обезьяны с помощью декораторов

Обертка имеет две функции

  • лучшие практики для декораторов
  • исправление обезьяны

Я делаю оба, чтобы иметь возможность условно изменить вызываемый метод. Я привел пример, основанный на версии pandas. В то время как это работает, я прибегаю к патчированию обезьян, но не использую возможности обертывания. Как можно использовать обертку для исправления альтернативного метода?

import pandas as pd
import wrapt, inspect
from distutils.version import StrictVersion
def alt_impl(alt_fn, cond):
    @wrapt.decorator
    def wrapper(wrapped, instance, args, kwargs):
        nonlocal alt_fn
        if cond():
            # @staticmethod and @classmethod need to navigate to actual function
            if not inspect.isfunction(alt_fn):
                alt_fn = alt_fn.__func__
            # class instance methods need to be bound to class instance
            if instance is not None:
                alt_fn = alt_fn.__get__(instance, instance.__class__)
            return alt_fn(*args, **kwargs)
        else:
            return wrapped(*args, **kwargs)
    return wrapper

Пример использования

class alt_impl_example():
    def upgraded_pandas(self, args):
        print(f"upgraded {pd.__version__}") 

    @alt_impl(upgraded_pandas, lambda: StrictVersion(pd.__version__) >= StrictVersion("1.0.0")) 
    def pandas(self, args): 
        print(pd.__version__) 

t = alt_impl_example()
t.pandas({})
...