Найти - Пользователи
Полная версия: универсальный декоратор для вызова метода-родителя
Начало » Python для новичков » универсальный декоратор для вызова метода-родителя
1
skill
Привет всем!
Подскажите,как лучше сделать - есть класс, в нем есть некоторые методы. Есть еще один класс, который наследуется от первого. В нем переопределяются методы родителя, и, в зависимости от выполнения условия, в начале метода вызывается либо супер, либо нет.
Вопрос в том, как можно написать декоратор, чтобы каждый раз не дублировать код, а просто обернуть им нужные методы?

Что-то типа такого:

class A(object):
    def first(self, a,b):
        # some actions
        pass
   def second(self, a,b):
        # some other actions
        pass
class B(A):
    def first(self, a,b):
        if a>b:
            return super(B, self).first(a,b)
        #otherwise make actions
    @need_to_call_super
    def second(self,a,b):
        # here we are sure,  the code below will be executed only if condition "a>b" hasn't passed, otherwise super(B,self).second(a,b) was called 
        # code

JOHN_16
Сразу оговрюсь, даже мне самому не нравится это решение, мне кажется за счет super должно как то проще делаться, но пока никто не ответил выкладываю свой вариант:
# -*- coding: utf-8 -*-
def deco(func, *args, **kargs):
    def wrapper(*args, **kargs):
        if args[1]>args[2]:
            return getattr(args[0].__class__.mro()[1], func.__name__)(*args, **kargs)
        else:
            return func(*args, **kargs)
    return wrapper
class A(object):
    def first(self, a, b):
        return a+b
    def second(self, a, b):
        return 2*(a+b)
class B(A):
    @deco
    def first(self, a, b):
        return a*b
    @deco
    def second(self, a, b):
        return 2*a*b
b=B()
print b.first(2, 5)
print b.first(5, 2)
print b.second(2, 5)
print b.second(5, 2)
Вывод:
10
7
20
14

Как видно, если первый аргумент меньше второго, то используется метод класса B, если больше то метод класса родителя т.е. класса А
terabayt
ну вот немного переделав код JOHN_16
def deco(func):
    def wrapper(self, *args, **kwargs):
        if args[0] > args[1]:
            return getattr(super(self.__class__, self), func.__name__)(*args, **kwargs)
        return func(self, *args, **kwargs)
    return wrapper
JOHN_16
terabayt
спасибо что поправили. Я думаю именно так оно и должно выглядеть.
skill
JOHN_16
terabayt

Спасибо за оперативную помощь. То что надо!)
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB