Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 21, 2013 00:46:15

Solly
Зарегистрирован: 2013-10-16
Сообщения: 8
Репутация: +  0  -
Профиль  

Использование декоратора в своём классе и в дочернем

Как заставить чтобы декоратор мог работать и в своём классе и в дочернем…
Как поняла - чтобы в дочернем работал - надо его классметодом сделать… но тогда отказывается в собственном классе работать, или я его не правильно вызываю…

import logging  
module_logger = logging.getLogger('testlog')
class DecorTest(object):
    def __init__(self):
        print 'init'
        self.a=5
        self.b=8
        self.str='1234567890qwertyuikdfgh'
        self.logger = logging.getLogger('testlog.DecorTest')
        self.logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(formatter)
        self.logger.addHandler(ch)
    def printer(self):
        print self.a
    @classmethod
    def deco(cls, fn):
        def wrapped(self, *args, **kwargs):
             self.logger.debug('start deco %s %s'%(self.__class__, fn.__name__))
             self.printer()
             fn(self, *args, **kwargs)
             self.logger.debug('end deco %s'%(self.str))
        return wrapped
    @deco                     #А вот тут - не хочет работать, пробовала и со скобочками, и @DecorTest.deco....
    def myfunc(self):
        print '%s +%s = %s'%(self.a ,self.b, self.a+self.b)
class SubDeco(DecorTest):
    def __init__(self):
        DecorTest.__init__(self)
    @DecorTest.deco   #Тут нормально вызывается и работает
    def callfunc(self):
        print 'my SubDeco addition'
    def subcall(self):
        self.myfunc()
def main():
    DT=SubDeco()
    DT.callfunc()
    DT.subcall()
if __name__ == '__main__':
    main()

Отредактировано Solly (Окт. 21, 2013 00:53:17)

Офлайн

#2 Окт. 21, 2013 01:14:21

Solly
Зарегистрирован: 2013-10-16
Сообщения: 8
Репутация: +  0  -
Профиль  

Использование декоратора в своём классе и в дочернем

и еще в догонку - а можно ли и как декоратор, задекорированный как классметод обернуть еще одним декоратором - внутри базового класса?

Отредактировано Solly (Окт. 21, 2013 01:16:42)

Офлайн

#3 Окт. 21, 2013 05:01:17

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9741
Репутация: +  843  -
Профиль   Отправить e-mail  

Использование декоратора в своём классе и в дочернем

у тебя в методе класса используется self, тогда как никакого self туда не поступает
(это не относится к декораторам)

сделай сначала что-нибудь попроще, выделив только то, что нужно сделать; тогда, может, и получится
а то тут понамешано, а цель не ясна

Solly
Как заставить чтобы декоратор мог работать и в своём классе и в дочернем…
сначала сделай простой пример, где декоратор правильно работает в своём классе
потом сделай простой пример, где декоратор правильно работает в производном классе
а потом объедини их, если они получились оба по отдельности



Отредактировано py.user.next (Окт. 21, 2013 05:04:01)

Офлайн

#4 Окт. 21, 2013 07:15:57

Solly
Зарегистрирован: 2013-10-16
Сообщения: 8
Репутация: +  0  -
Профиль  

Использование декоратора в своём классе и в дочернем

по отдельности все нормально работает
- у тебя в методе класса используется self, тогда как никакого self туда не поступает
— ну а как его туда запихнуть?

Офлайн

#5 Окт. 21, 2013 08:40:47

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

Использование декоратора в своём классе и в дочернем

классметод не нужен же

import logging  
module_logger = logging.getLogger('testlog')
def deco(fn):
    def wrapped(self, *args, **kwargs):
         self.logger.debug('start deco %s %s'%(self.__class__, fn.__name__))
         self.printer()
         fn(self, *args, **kwargs)
         self.logger.debug('end deco %s'%(self.str))
    return wrapped
 
class DecorTest(object):
    def __init__(self):
        print 'init'
        self.a=5
        self.b=8
        self.str='1234567890qwertyuikdfgh'
        self.logger = logging.getLogger('testlog.DecorTest')
        self.logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(formatter)
        self.logger.addHandler(ch)
        
    def printer(self):
        print self.a
        
    @deco                     #А вот тут - не хочет работать, пробовала и со скобочками, и @DecorTest.deco....
    def myfunc(self):
        print '%s +%s = %s'%(self.a ,self.b, self.a+self.b)
        
class SubDeco(DecorTest):
    def __init__(self):
        DecorTest.__init__(self)
        
    @deco #@DecorTest.deco   #Тут нормально вызывается и работает
    def callfunc(self):
        print 'my SubDeco addition'
        
    def subcall(self):
        self.myfunc()
        
def main():
    DT=SubDeco()
    DT.callfunc()
    DT.subcall()
    
if __name__ == '__main__':
    main()

Solly
и еще в догонку - а можно ли и как декоратор, задекорированный как классметод обернуть еще одним декоратором - внутри базового класса?
да, только @classmethod должен быть последним декоратором, там какое-то связывание происходит

Офлайн

#6 Окт. 21, 2013 12:12:52

Solly
Зарегистрирован: 2013-10-16
Сообщения: 8
Репутация: +  0  -
Профиль  

Использование декоратора в своём классе и в дочернем

sergeek
Спасибо

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version