Как украсить унаследованный метод - Python - PullRequest
0 голосов
/ 12 марта 2019

Я должен украсить унаследованный метод, но он украшает все унаследованные методы. По сути, мне нужно создать декоратор, который будет украшать только один метод из класса.

Тест выглядит так

@my_decorator
    class TestClass(Subclass):
        pass

t = TestClass()
t.say_hi

Допустим, мой подкласс выглядит следующим образом

class SubClass():
    def __init__(self):
        pass

    def say_hi():
        print("Hi")

    def say_wow():
        print("wow")

Теперь я должен сделать my_decorator, который должен унаследовать унаследованную функцию say_hi() до print("*****"), прежде чем он напечатает "Привет"

Я пытался сделать это так, но декоратор применим ко всем методам из SubClass

def my_decorator(cls)
    def say_hi():
        print("*********")
        cls.say_hi()

    return say_hi()

Естественно, это применимо к каждой функции подкласса, но как мне сделать так, чтобы она применялась только к функции say_hi()? -Также возвращает TypeError "NoneType" object is not callable

Ответы [ 2 ]

1 голос
/ 12 марта 2019

Сначала давайте исправим SubClass, потому что методы экземпляра требуют явного параметра экземпляра во время определения:

class SubClass():
    def __init__(self):
        pass

    def say_hi(self):
        print("Hi")

    def say_wow(self):
        print("wow")

Теперь вы хотите, чтобы декоратор заменил метод say_hi на метод, который печатает '****' перед вызовом исходного метода. Давайте напишем декоратор, который просто делает это (*):

def my_decorator(cls):
    orig = cls.say_hi          # save the original method
    def say_hi(self):          # define a new one
        print('****')
        return orig(self)      # ... calling the original method
    cls.say_hi = say_hi        # replace the method in the class
    return cls

Затем вы можете использовать:

@my_decorator
class TestClass(SubClass):
    pass
t = TestClass()
t.say_hi()

и получите, как и ожидалось:

****
Hi

(*) это очень простой декоратор, который может заменить только метод say_hi(self): ни другое имя, ни дополнительные параметры, но декораторы могут быть намного умнее ...

0 голосов
/ 12 марта 2019

Если вы хотите декорировать метод, то декорируйте метод, а не класс, который его содержит. Если вы хотите новый класс, то декоратор, примененный к классу, должен вернуть класс.

def print_banner(f):
    def _(*args, **kwargs):
       print("****")
       f(*args, **kwargs)
    return _

class SubClass():
    def __init__(self):
        pass

    @print_banner
    def say_hi(self, ):
        print("Hi")

    def say_wow(self):
        print("wow")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...