Дизайн декоратора: выполнение метода, только если он был переопределен - PullRequest
1 голос
/ 03 июня 2011

Я наткнулся на хитрый вопрос по питону.Дано ( updated ):

class A(object):
    def run(self):
        # This makes possible to determine if 'run' was overridden
        if self.run.im_func != A.run.im_func:
            print('Running in {0}'.format(self.__class__.__name__))

class B(A):
    def run(self):
        super(B, self).run()

class C(A):
    pass

b = B()
c = C() 
b.run()
>>> Running in B

c.run()
>>> # nothing :)

Как бы вы разработали декоратор @runoverriden, который бы выполнял работу условного оператора в A.run ()?

Обновление: Целью этого кода является то, что A.run () должен регистрировать вызовы run (), только если он был переопределен.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 03 июня 2011

Если я понимаю, что вы хотите:

import functools
def runoverridden(f):
    @functools.wraps(f)
    def wrapper(self, *args, **kw):
        if getattr(self, f.__name__).im_func != wrapper:
            return f(self, *args, **kw)
    return wrapper

class A(object):
    @runoverridden
    def run(self):
        print('Running in A')

class B(A):
    def run(self):
        super(B, self).run()
        print('Running in B')

class C(A):
    pass

b = B()
c = C() 
b.run()
c.run()
0 голосов
/ 03 июня 2011

Звучит так, как вы хотите Азбука .В частности, абстрактный метод декоратор.

...