преобразование методов класса с использованием метода декоратора родительского класса

#python #python-3.x #oop #decorator

#python #python-3.x #ооп #декоратор

Вопрос:

 def greeting_decorator(original_function):
    def return_function(*args):
        name = 'John'
        return f'Hi, I'm {name}, fullname: {original_function(*args)}'
    return return_function

@greeting_decorator
def greeting(name, surname):
    return f'{name} {surname}'

print(greeting('John', 'Doe'))
  

Выше у меня есть простая функция декоратора, которая работает по назначению.
Я хотел бы сделать что-то подобное, но с унаследованным классом.
Как я могу унаследовать функцию декоратора, подобную этой:

 class Guy:

    def __init__(self, name):
        self.name = 'John'

    def greeting_decorator(self, original_function):
        def return_function(*args):
            return f'Hi, I'm {self.name}, fullname: {original_function(*args)}'
        return return_function


class GuyWithSurname(Guy):

    def __init__(self, name, surname):
        super().__init__(name)
        self.surname = surname

    @greeting_decorator # <----- here
    def __str__(self):
        return f'{self.name} {self.surname}'
    
JohnDoe = GuyWithSurname('John', 'Doe')
print(JohnDoe)
  

Комментарии:

1. Если вы всегда знаете родительский класс, вы можете сделать @Guy.greeting_decorator вместо этого.

2. Вы должны использовать Guy.greeting_decorator

Ответ №1:

Если вы уверены, что родительский класс всегда будет Guy , вы можете просто аннотировать через @Guy.greeting_decorator :

 class Guy:

    def __init__(self, name):
        self.name = 'John'

    def greeting_decorator(original_function):
        def return_function(self, *args):
            return f'Hi, I'm {self.name}, fullname: {original_function(self, *args)}'
        return return_function

class GuyWithSurname(Guy):

    def __init__(self, name, surname):
        super().__init__(name)
        self.surname = surname

    @Guy.greeting_decorator # <----- here
    def __str__(self):
        return f'{self.name} {self.surname}'

JohnDoe = GuyWithSurname('John', 'Doe')
  

Таким образом, при вызове print(JohnDoe) он будет выводить Hi, I'm John, fullname: John Doe .

Обратите внимание, что мне пришлось изменить greeting_decorator и return_function параметры для правильной обработки self .