Python / Как декорировать методическую часть класса без изменения указанного класса? - PullRequest
0 голосов
/ 09 мая 2020

ОСНОВНАЯ ПРОБЛЕМА

В качестве примера скажем, что я хотел бы украсить метод split() класса str (пример представляет то, что я пытаюсь сделать, за исключением того, что я хотел бы украсить метод agg класса pandas DataFrame).

По крайней мере, я получаю ту же ошибку.

Я предпочитаю не использовать @ и не создавать дочерний класс str для простоты (и, возможно, именно поэтому он не работает ...)

Я столкнулся со следующей проблемой.

def bla_addition(word):
    def decorator(func):
        def wrapper(*args, **kwargs):
            # Modify `my_list`
            word2 = word + 'bla'
            return  word2.func(*args, **kwargs)
        return wrapper
    return decorator

added = bla_addition('blu')
split = added(str.split)
new_word = split('l')

Произошла ошибка: AttributeError: 'str' object has no attribute 'func'

Пожалуйста, у вас есть идеи, как я могу это сделать?

Благодарю за вашу помощь и советы.

PS: Я пошел по пути использования декоратора без @ здесь: https://www.python-course.eu/python3_decorators.php Я считаю очень полезным избежать создания новой однострочной функции для split.

ПОБОЧНЫЙ ВОПРОС

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

def bla_addition(word):
    def decorator(func):
        def wrapper(*args, **kwargs):
            # Modify `my_list`
            word += 'bla'                #-> parameter word modified
            return  word.func(*args, **kwargs)
        return wrapper
    return decorator

added = bla_addition('blu')
split = added(str.split)
new_word = split('l')

Ошибка: UnboundLocalError: local variable 'word' referenced before assignment

1 Ответ

0 голосов
/ 09 мая 2020

Хорошо, только что узнал благодаря этому объяснению: https://www.bogotobogo.com/python/python_differences_between_static_method_and_class_method_instance_method.php

Другой способ вызова - перебор имени класса, как показано ниже:

Вот рабочий код.

def bla_addition(word):
    def decorator(func):
        def wrapper(*args, **kwargs):

            # Modify `my_list`
            word2 = word + 'bla'
            return  func(word2, *args, **kwargs)
        return wrapper
    return decorator

added = bla_addition('blu')
split = added(str.split)
new_word = split('l')

Bests,

...