Существуют ли в GoLang декораторы подобные Python?

1,076 views
Skip to first unread message

sys_dev

unread,
Dec 24, 2013, 3:46:22 PM12/24/13
to gola...@googlegroups.com
Доброе, $(Время-Суток)!

Мне хочется решить следующую задачу:

func SuperFunction() {
PrintBeginMsg()
doSomething()
PrintEndMsg()
}

func PrintBeginMsg() {
fmt.Println(GetCallerName() + " " + "Started...")
}

func PrintEndMsg() {
fmt.Println(GetCallerName() + " " + "Done")
}

Другими словами для каждой функции я хочу выводить сообщение о начале ее работы и завершении с ее названием.
На Python я бы написал декоратор, но в GoLang не вижу.

Пока читаю этот слайд: http://talks.golang.org/2013/go4python.slide#35 , но понимания пока не наступает.

Как подобная ситуация решается на Go ?

Andrew Zinenko

unread,
Dec 24, 2013, 3:52:30 PM12/24/13
to gola...@googlegroups.com

-- 
Andrew Zinenko
Sent with Sparrow

--
Вы получили это сообщение, поскольку подписаны на группу GoLang Russian.
 
Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес golang-ru+...@googlegroups.com.
Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out.

NtVisigoth

unread,
Dec 24, 2013, 3:57:59 PM12/24/13
to gola...@googlegroups.com
Не совсем. В Python у нас неявным образом создается новый объект функции, который внутри себя вызывает явно написанный код.

def superFunction()
   pass

мы явно видим написанный код. Но вот если написать так:

@begin_end
def superFunction()
   pass

то мы уже как бы "не замечаем" что по сути происходит в begin_end. Мне хочется на Go такое же решение чтобы вспомогательный код не слишком мешал чтению основного кода. 

В вашем решении Вы явно пишите Notify, таким образом вы "гвоздями прибиваете" внимание читающего код!



25 декабря 2013 г., 0:52 пользователь Andrew Zinenko <zine...@gmail.com> написал:

--
Вы получили это сообщение, так как подписаны на группу "GoLang Russian".
Чтобы отказаться от подписки на эту тему, перейдите на страницу https://groups.google.com/d/topic/golang-ru/rE_GL9QmKaQ/unsubscribe.
Чтобы отказаться от подписки на эту группу и все входящие в нее темы, отправьте электронное письмо на адрес golang-ru+...@googlegroups.com.

Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out.



--
In Russian:
С уважением, Дмитрий Андриянков.
ICQ:     429267915
skype:  dmitry.andriyankov


Andrew Zinenko

unread,
Dec 24, 2013, 4:00:10 PM12/24/13
to gola...@googlegroups.com
Не надо писать в Go на Python – revel получится.

-- 
Andrew Zinenko
Sent with Sparrow

NtVisigoth

unread,
Dec 24, 2013, 4:03:49 PM12/24/13
to gola...@googlegroups.com
Есть две ситуации : 1) Писать на языке и 2) Писать с использованием языка. Отличается в том, что в одной ситуации программист мирится с ограничениями языка. А во второй ситуации программист парит "над языком". Я к тому что мне не важно, что и на что будет похожим. Есть задача и ее надо решать, вот именно это и волнует, а уж на что именно это будет похожим меня не особо волнует!


25 декабря 2013 г., 1:00 пользователь Andrew Zinenko <zine...@gmail.com> написал:

Олег Булатов

unread,
Dec 24, 2013, 4:34:32 PM12/24/13
to gola...@googlegroups.com
Сделать подобие декоратора, конечно, можно
 
Однако это не "писать с использованием языка", а "попытка писать на python с использованием go".
Строгая типизация, отсутствие __name__ и все-такое дают о себе знать.
 
Кажется следующий вариант менее чужеродный для Go:
 
25.12.2013, 01:03, "NtVisigoth" <ntvis...@gmail.com>:

Denis Portnov

unread,
Dec 24, 2013, 9:31:53 PM12/24/13
to gola...@googlegroups.com
для приведенного примера вариант конечно есть http://play.golang.org/p/NZnaoCgIUC
но надо понимать что Go строго типизированный язык, и когда нужно будет чтоб функции принимали/возвращали значения, придется копать reflect
и код начнет сильно пахнуть

А декоратор как ОО паттерн в Go довольно легко реализуется на интерфейсах http://play.golang.org/p/4tk5PNa9iK

Но в целом я согласен, зачем писать на Go как на питоне если есть питон

Konstantin Cherkasoff

unread,
Dec 25, 2013, 10:21:56 AM12/25/13
to gola...@googlegroups.com
> Не надо писать в Go на Python – revel получится.

О, любопытно. А что там в Revel такого?

--
Konstantin Cherkasoff

sys_dev

unread,
Dec 28, 2013, 6:16:05 AM12/28/13
to gola...@googlegroups.com
Денис, Ваш вариант ничем не лучше Выше предложенных. Попробую пояснить в чем крутость python-декораторов.

1) Вам не надо создавать какой-либо объект-обертку! Все что Вам надо это написать "@" и имя функции декоратора! Одну строку!
2) В случае python-декораторов функция декоратор почти не видна и вы видете как правило только '@' и основное внимание сразу же цепляются только на саму декорируемую функцию, что без условно является верным и правильным, т.к. ведет к повышению читабельности кода.

Более-того Ваши слова про строго типизированность не совсем понятны. Как типизированность может мешать добавлению "декораторов" ?

Как бы я хотел и ожидал бы от Go?

decor(StartAndEndMsgWriter)
func WriteUnpackedFile() {
// more code
}

В этом куске кода мое внимание приковывается сразу же на тело функции, где сейчас "// more code"

Вообщем я бы хотел чтобы в Go появились или подобные аннотации в Java или декораторы подобные в Python.

среда, 25 декабря 2013 г., 6:31:53 UTC+4 пользователь Denis Portnov написал:

Morozov Alexandr

unread,
Dec 28, 2013, 8:58:43 AM12/28/13
to gola...@googlegroups.com
Декоратор в питоне - это всего лишь синтаксический сахар для функции, которая принимает функцию и возвращает функцию. В Go вы не можете написать функции, которые будут принимать ПРОИЗВОЛЬНЫЕ функции, так как функции имеют определенный тип (например func () в вашем случае). Декораторы несомненно удобная вещь в питоне, но для статически типизированных языков аналогичной реализации не получится(только если генерацией кода).

Denis Portnov

unread,
Dec 28, 2013, 1:11:40 PM12/28/13
to gola...@googlegroups.com

On Saturday, December 28, 2013 3:16:05 PM UTC+4, sys_dev wrote:
Денис, Ваш вариант ничем не лучше Выше предложенных. Попробую пояснить в чем крутость python-декораторов.

1) Вам не надо создавать какой-либо объект-обертку! Все что Вам надо это написать "@" и имя функции декоратора! Одну строку!
с питоном мало знаком, я, не разобравшись, привел объект как пример ОО паттерна
теперь посмотрев, я так понимаю это что-то из области функционального программирования
"крутость" оставлю за скобками, это применимо и наверное логично для питона, в других языках свои реализации и подходы

2) В случае python-декораторов функция декоратор почти не видна и вы видете как правило только '@' и основное внимание сразу же цепляются только на саму декорируемую функцию, что без условно является верным и правильным, т.к. ведет к повышению читабельности кода.
я лично (и насколько я могу судить, авторы Go тоже) не в восторге от таких штук, это метапрограммирование и очень спорно насколько это повышает читабельность и структурированность кода


Более-того Ваши слова про строго типизированность не совсем понятны. Как типизированность может мешать добавлению "декораторов" ?
в Go функция это тип, соответственно например функция func (i int) int и func (i int) bool это разные типы, так как разные возвращаемые значения
соответственно обертку можно определить только на один тип функции


Как бы я хотел и ожидал бы от Go?

decor(StartAndEndMsgWriter)
func WriteUnpackedFile() {
// more code
}

В этом куске кода мое внимание приковывается сразу же на тело функции, где сейчас "// more code"

Вообщем я бы хотел чтобы в Go появились или подобные аннотации в Java или декораторы подобные в Python.

Многие почему-то хотят сделать из Go тот язык на котором они привыкли писать, по мне это странно
Мне как раз нравится в язые отсутствие этих мета наворотов (есть тэги, но это не совсем то). Есть код и он делает то что написано и не надо изучать мета язык, макросы и пр. чтобы понять что происходит в коде

А возвращаясь к начальному посту, есть смысл понять задачу и как её решить средствами языка

Message has been deleted

Alexey Khalyapin

unread,
Feb 3, 2014, 1:27:30 AM2/3/14
to gola...@googlegroups.com
Думаю, правильнее использовать замыкания. 
Т.к. язык типизированный, сигнатура декоратора должна совпадать с сигнатурой декорируемой функции.

Мой вариант - http://play.golang.org/p/GrFV4neDBG



среда, 25 декабря 2013 г., 0:46:22 UTC+4 пользователь sys_dev написал:

Tyranron

unread,
May 14, 2014, 5:52:19 PM5/14/14
to gola...@googlegroups.com
Пусть тред уже и поутих, тем не менее, возможно, кому-то пригодится.
Вариант Alexey, но с помощью функциональных типов:

Достаточно непривычная и необычная вещь, получается этакий гибрид на стыке функциональной и объектной парадигмы. =)

вторник, 24 декабря 2013 г., 22:46:22 UTC+2 пользователь sys_dev написал:

Konstantin Kulikov

unread,
May 15, 2014, 5:21:52 AM5/15/14
to gola...@googlegroups.com
Зачем такие сложности? Для решения оригинального вопроса достаточно одного defer
Reply all
Reply to author
Forward
0 new messages