Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 22, 2016 14:29:49

rascally_rabbit
Зарегистрирован: 2016-09-22
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

декоратор

Добрый день.

Помогите, пожалуйста, разобраться. Изучаю самостоятельно Python 3.
Делаю задание по декораторам - написать декратор для функции, при вызове функции печатает “старт”, после окончания - “end”
Код:

 def decorator_func(func):
	print("start")
	def result(*args, **kwargs):
		func(*args, **kwargs)
	print("end")
	# return result
@decorator_func
def test(a, b):
	print(a * b)
test(2, 5)

Ошибка:
 start
end
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    test(2, 5)
TypeError: 'NoneType' object is not callable

Что я делаю не так?

Офлайн

#2 Сен. 22, 2016 14:38:03

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

декоратор

 # return result
Зачем оно закомментировано? Раскомментируйте и у вас останется всего одна ошибка.

Офлайн

#3 Сен. 22, 2016 14:43:12

rascally_rabbit
Зарегистрирован: 2016-09-22
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

декоратор

Да, но задание не выполнится.
Результат:

 start
end
10

Офлайн

#4 Сен. 22, 2016 15:17:48

rascally_rabbit
Зарегистрирован: 2016-09-22
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

декоратор

Рабочий вариант:

 def decorator_func(func):
	def result(*args, **kwargs):
		print("start")
		func(*args, **kwargs)
		print("end")
	return result
@decorator_func
def test(a, b):
	print(a * b)
test(2, 5)

Понял, что еще про декораторы нужно почитать и разобраться )))

Офлайн

#5 Сен. 22, 2016 15:38:29

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

декоратор

А хотите интереснее задание?

Попробуйте создать параметризированный декоратор.

Офлайн

#6 Сен. 22, 2016 15:50:35

rascally_rabbit
Зарегистрирован: 2016-09-22
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

декоратор

4kpt_IV
А хотите интереснее задание?Попробуйте создать параметризированный декоратор.
Спасибо )))
Вечером буду разбираться.
Может примерную задачу сформулируете?

Офлайн

#7 Сен. 22, 2016 16:13:09

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

декоратор

rascally_rabbit
пусть декоратор принимает в качестве параметра сообщение которое должен печатать при начале и после выполнения функции. В вашем случае оно жестко прописано, а вот параметризация декоратора позволит вам иметь 1 декоратор для разных случаев, вместо написания N разных



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

Офлайн

#8 Сен. 23, 2016 11:08:01

rascally_rabbit
Зарегистрирован: 2016-09-22
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

декоратор

Правильно?

 def add_msg(start_msg, end_msg):
	def some_decorator(func):
		def result(*args, **kwargs):
			print(start_msg, func.__name__)
			func(*args, **kwargs)
			print(end_msg, func.__name__)
		return result
	return some_decorator
@add_msg("старт функции", "завершение функции")
def test(a, b):
	print(a * b)
test(2, 5)

Отредактировано rascally_rabbit (Сен. 23, 2016 11:24:25)

Офлайн

#9 Сен. 23, 2016 13:03:57

4kpt_IV
Зарегистрирован: 2016-01-08
Сообщения: 999
Репутация: +  49  -
Профиль   Отправить e-mail  

декоратор

Было бы все хорошо, но Ваш декоратор пожрет все атрибуты функции. Строки кода, ее имя и т.п. Посмотрите в сторону functools, а именно wraps, чтобы сделать “совсем по-феншую”…

Офлайн

#10 Сен. 23, 2016 14:18:50

rascally_rabbit
Зарегистрирован: 2016-09-22
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

декоратор

Спасибо за совет.
Буду дальше разбираться )))

Отредактировано rascally_rabbit (Сен. 23, 2016 14:32:33)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version