Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 14, 2015 00:20:41

skill
От:
Зарегистрирован: 2012-03-20
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

универсальный декоратор для вызова метода-родителя

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

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

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



Офлайн

#2 Фев. 14, 2015 02:19:45

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

универсальный декоратор для вызова метода-родителя

Сразу оговрюсь, даже мне самому не нравится это решение, мне кажется за счет 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, если больше то метод класса родителя т.е. класса А



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#3 Фев. 14, 2015 04:26:46

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

универсальный декоратор для вызова метода-родителя

ну вот немного переделав код 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



————————————————
-*- Simple is better than complex -*-

Офлайн

#4 Фев. 14, 2015 08:39:25

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

универсальный декоратор для вызова метода-родителя

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



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#5 Фев. 14, 2015 10:17:27

skill
От:
Зарегистрирован: 2012-03-20
Сообщения: 10
Репутация: +  0  -
Профиль   Отправить e-mail  

универсальный декоратор для вызова метода-родителя

JOHN_16
terabayt

Спасибо за оперативную помощь. То что надо!)



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version