Вызов различных методов родительского класса с одним декоратором - PullRequest
0 голосов
/ 18 ноября 2018

Так что в принципе моя проблема выглядит следующим образом.

class A():
    def func(self):
        return 3

class B():
    def func(self):
        return 4

class AA(A):
    def func(self):
        return super(AA, self).func

class BB(B):
    def func(self):
        return super(BB, self).func

Функция func выполняет некоторую работу, и одна из вещей, которую она делает, - это получение какого-либо атрибута (или запускающего метода или чего-либо еще) из своего родительского класса.

Поскольку func изначально выполняет одинаковую логику в обоих случаях (за исключением того, что изменяется только родительский класс), я бы хотел сделать это с декораторами.

Возможно ли это? если да, то как это сделать? Должен ли я как-то передать родительский класс в качестве аргумента?

Я буду очень благодарен за ответы, которые меня уже давно беспокоят.

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

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

def my_decorator(cls):
    def call_super_func(self):
        return super(type(self), self).func()

    setattr(cls, 'call_super_func', call_super_func)
    return cls

class A():
    def func(self):
        print('in A.func')
        return 3

class B():
    def func(self):
        print('in B.func')
        return 4

@my_decorator
class AA(A):
    def func(self):
        print('in AA.func')
        return self.call_super_func()

@my_decorator
class BB(B):
    def func(self):
        print('in BB.func')
        return self.call_super_func()


aa = AA()
aa.func()
bb = BB()
bb.func()

Выход:

in AA.func
in A.func
in BB.func
in B.func

Конечно, вы можете избавиться от необходимости делать это, просто определив базовый класс для A и B, в котором есть метод call_super_func(), который они оба потом наследуют.

0 голосов
/ 18 ноября 2018

Нет необходимости использовать super для доступа к атрибутам данных родительского класса.

Классу также не нужен родительский элемент для доступа к атрибутам данных.

Вы можете использовать миксин, чтобы сделать работу:

# A and B stay the same - they still have a c attribute
class A():
    c = 3

class B():
    c = 4  # I've changed B to make it clear below

#Instead have a mixin which defines func()
class Mixin:
    def func(self):
        # func has its behaviour here
        return self.c

class AA(Mixin, A):
    pass
class BB(Mixin, B):
    pass

a = AA()
b = BB()
print(a.func())
print(b.func())

Вывод:

3
4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...