Гость
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Декораторы в Pyhton / 9 сообщений из 9, страница 1 из 1
18.10.2017, 17:40
    #39538315
AlexGru
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Декораторы в Pyhton
Только начинаю изучать.
Суть такая, есть метод класса возвращающий что-то
Код: python
1.
2.
3.
4.
5.
6.
class TClass:

  def func1(self):
    #тут делается море калькуляции
    #return 3000
    print('Метод func1 вызван, вернул 3000')



Требуется написать класс с декоратором вокруг функции func1.

Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
from ClassTClass import *

class ChildTClass(TClass):

 def my_new_decorator(self,function_to_decorate):
   def the_wrapper_around_the_original_function(self):
     print ('Я - код, который отработает до вызова функции')
     function_to_decorate(self)
     print('А я - код, срабатывающий после')
   return the_wrapper_around_the_original_function



И далее вызов
Код: python
1.
2.
3.
4.
5.
6.
7.
from ClassChildTClass import ChildTClass

c = ChildTClass()

print('--------------------------------------')
stand_alone_function = c.my_new_decorator(c.func1())
print('--------------------------------------')



Вывод
Код: python
1.
2.
3.
--------------------------------------
Метод func1 вызван, вернул 3000
--------------------------------------



Вопрос,
1) почему произошел реальный вызов функции func1? я ведь только в переменную stand_alone_function получаю функцию
the_wrapper_around_the_original_function таким вызовом
stand_alone_function = c.my_new_decorator(c.func1())

2) Раз вызов func1 произошел, то уж почему тогда без print_ов
print ('Я - код, который отработает до вызова функции')
print('А я - код, срабатывающий после')

?
...
Рейтинг: 0 / 0
18.10.2017, 22:07
    #39538421
skyANA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Декораторы в Pyhton
AlexGruпочему произошел реальный вызов функции func1?
Потому как c.func1() - это и есть реальный вызов функции func1
Скобочки круглые уберите.
...
Рейтинг: 0 / 0
19.10.2017, 09:40
    #39538513
AlexGru
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Декораторы в Pyhton
skyANAПотому как c.func1() - это и есть реальный вызов функции func1
Скобочки круглые уберите.

Спасибо, помогло, сейчас код
Код: python
1.
2.
3.
4.
5.
6.
7.
from ClassChildTClass import ChildTClass

c = ChildTClass()

print('--------------------------------------')
stand_alone_function = c.my_new_decorator(c.func1)
print('--------------------------------------')



возвращает
Код: python
1.
2.
--------------------------------------
--------------------------------------



Но если попытаться вызвать функцию, то ошибки
Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
from ClassChildTClass import ChildTClass

c = ChildTClass()

print('--------------------------------------')
stand_alone_function = c.my_new_decorator(c.func1)
stand_alone_function()
print('--------------------------------------')


Traceback (most recent call last):
  File "C:/PythonStudy/Work.py", line 7, in <module>
    stand_alone_function()
TypeError: the_wrapper_around_the_original_function() missing 1 required positional argument: 'self'



В чем проблема?
...
Рейтинг: 0 / 0
19.10.2017, 14:11
    #39538719
skyANA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Декораторы в Pyhton
AlexGruВ чем проблема?
ИМХО в том, что Вы сами не понимаете, что декорируете и зачем.

A guide to Python's function decorators
...
Рейтинг: 0 / 0
22.10.2017, 23:55
    #39540192
AlexGru
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Декораторы в Pyhton
skyANAИМХО в том, что Вы сами не понимаете, что декорируете и зачем.


Спасибо, статья хорошая, прочитал. Сделал.
Получилось так:
Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
class TClass:

  def func1(self):
    print('Метод func1 вызван')

---------------------------------------------------------------------------
from FileTClass import *

class ChildTClass(TClass):

    def check_cache_decorator(self,func):
        def wrapper():
            print('Я - код, который отработает до вызова функции')
            func()
            print('А я - код, срабатывающий после')
        return wrapper

---------------------------------------------------------------------------
from FileChildTClass import *

c = ChildTClass()

print(c.func1.__name__)
print(c.func1.__module__)
print('----------------------------------------')
c.func1()
print('----------------------------------------')
print('                                        ')
c.func1=c.check_cache_decorator(c.func1)
c.func1()
print('----------------------------------------')
print(c.func1.__name__)
print(c.func1.__module__)



Результат
Код: python
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
func1
FileTClass
----------------------------------------
Метод func1 вызван
----------------------------------------
                                        
Я - код, который отработает до вызова функции
Метод func1 вызван
А я - код, срабатывающий после
----------------------------------------
wrapper
FileChildTClass




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

c.func1=c.check_cache_decorator(c.func1)

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

c.func1=XXXXXXXX(YYYYYYYYYYYYY(c.check_cache_decorator(c.func1)))
...
Рейтинг: 0 / 0
23.10.2017, 17:21
    #39540655
skyANA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Декораторы в Pyhton
AlexGruСейчас вопрос, в том, можно ли как-то иначе записать применение декорирования?
Вместо этого

c.func1=c.check_cache_decorator(c.func1)

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

c.func1=XXXXXXXX(YYYYYYYYYYYYY(c.check_cache_decorator(c.func1)))
Хм, очевидно, что выражение, записанное в одну строку
Код: python
1.
a = a + b + c + d


можно представить в несколько строк
Код: python
1.
2.
3.
a = a + b
a = a + c
a = a + d


То есть
Код: python
1.
2.
3.
c.func1 = c.check_cache_decorator(c.func1)
c.func1 = yyyyyyyyyyyyy_decorator(c.func1)
c.func1 = xxxxxxxxxxxxx_decorator(c.func1)
...
Рейтинг: 0 / 0
24.10.2017, 16:33
    #39541215
AlexGru
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Декораторы в Pyhton
skyANA,

Спасибо, это понятно. А с использованием @ ?
...
Рейтинг: 0 / 0
26.10.2017, 18:14
    #39542780
skyANA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Декораторы в Pyhton
AlexGruskyANA,

Спасибо, это понятно. А с использованием @ ?
?
...
Рейтинг: 0 / 0
11.12.2017, 15:06
    #39567703
kealon(Ruslan)
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Декораторы в Pyhton
AlexGruskyANA,

Спасибо, это понятно. А с использованием @ ?ну так они и так отдельно пишутся
...
Рейтинг: 0 / 0
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Декораторы в Pyhton / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]