Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.fds-net.ru/ashowflat.php?Number=11890088&src=&showlite=l
Дата изменения: Unknown
Дата индексирования: Wed Apr 13 12:16:25 2016
Кодировка: Windows-1251
Контекст отладочных сообщений - Public forum of MSU united student networks
Technical >> Development (Archive)

Страницы: 1
Vlad : Контекст отладочных сообщений     13.03.2014 17:23    | Reply | Edit |
3
Допустим, есть такой код:
code:
def process_wheel(wheel): if problem with the wheel: log(problem with the wheel) def process_bicycle(bicycle): for wheel in bicycle.wheels: process_wheel(wheel) ... for bicycle in bicycles: process_bicycle(bicycle)


Неудобство в том, что напечатается проблематичное колесо, но не будет понятно к какому велосипеду оно относится.

Что можно сделать?

Можно всегда печатать текущий велосипед. Но их может быть много.

Можно передавать велосипед дополнительным аргументом в process_wheel, но это как-то мерзко потому что он нужен исключительно в отладочных целях.

Можно сделать process_wheel методом класс BicycleProcessor, у которого в состоянии есть current_bicycle. Но это ООП.

Вдобавок, недостаток последних двух подходов в том, что колеса бывают не только у велосипедов.


Мне недавно пришла в голову такая идея. Ввести контекст-менеждер, который будет содержать отладочный, хм, контекст. Функция печатающая сообщение проверяет, в каких контексах она находится (динамически), и если данные контекста еще не печатались, печатает их непосредственно перед тем сообщением, которое ей передали.

Типа, код будет выглядеть так:
code:
def process_bicycle(bicycle): with LogContext(bicycle): for wheel in bicycle.wheels: process_wheel(wheel)


А печатать будет примерно следующее:
code:
in the context bicycle#666: problem with the wheel#1 probelm with the wheel#2 in the context bicycle#888: problem with the wheel#2


Бонус: контексты могут быть вложенными.

Получаются типа такие domain-specific stack traces.

---
Никакого вопроса тут нет, просто решил поделиться.

maloi   [re:Vlad]   13.03.2014 19:50    | Reply | Edit |
4
я так понял ты решил переизобрести MDC/NDC?

Vlad   [re:maloi]   13.03.2014 20:23    | Reply | Edit |
0
Похоже что да. А NDC умеет печататься как у меня в примере, или только тупо

code:
in the context bicycle#666: problem with the wheel#1 in the context bicycle#666: probelm with the wheel#2 in the context bicycle#888: problem with the wheel#2

?

maloi   [re:Vlad]   13.03.2014 21:35    | Reply | Edit |
0
Это уже от appender-а зависит, если он умеет не выводить повторяющийся контекст дважды, то почему бы и нет? Ну а вообще если у нас несколько потоков и в лог не выводится id потока, то такая оптимизация может выйти боком.

Fj_   [re:Vlad]   14.03.2014 03:17    | Reply | Edit |
6
Я об этой проблеме много думал.

Я думал о ней так: я хочу видеть в стектрейсе упавшей прожрамки значения интересных переменных. Или в эксепшене, если прожрамка упала не совсем. Причем эти переменные и их значения выводятся для всех стекфреймов в стектрейсе.

Твое решение мне в общем нравится, но только оно будет приводить к сильно повышенному нестингу. Вот если б я это писал на плюсах, решение было бы довольно очевидным: взять макрос для уникального имени переменной ("logging_context" + __FILE__ + __LINE__ покатит), дальше RAII и добавлять значения при помощи WITH_CONTEXT(wheel.id) (которое __FILE__ и __LINE__ тоже в сообщение добавит отдельно).

Питон может в RAII-style inline "do something in current scope, undo that when leaving the scope" без дичайших извращений?


Vlad   [re:Fj_]   14.03.2014 16:18    | Reply | Edit |
1
В с++ прикольно получается!
Я бы предпочел группировать переменные по domain specific фреймам, а не получать их длинным однородным списком, но это тоже легко делается добавлением еще одной raii-штуки.

Но что именно тебя в питоне смущает, что надо в четыре пробела отступ делать после with? Так это же не на каждую отладочную переменную, а на каждый контекст только.
Ну и в любом случае можно так:
code:
@interesting_pseudo_frame def process_bicycle(bicycle): interesting_value("bicycle.id", bicycle.id) ...



Fj_   [re:Vlad]   15.03.2014 03:32    | Reply | Edit |
2
Эм, а как ты это сделаешь, interesting_value динамически не появится в обернутой функции. Или ты совсем кривой хак имеешь в виду?

Но это навело меня на мысль кстати, что наверное хочется обычно сохранять именно значения аргументов функции (ибо если кому нужно вычисленное сохранить - пусть сохраняет в вызываемой функции). И вот тут вполне уместно сделать декоратор который их сохраняет. В третьем питоне (я не знаю, его нормальные люди уже используют?) можно даже как бы теги добавлять к аргументам.

> Но что именно тебя в питоне смущает, что надо в четыре пробела отступ делать после with?

Да, дико смущает. Код должен быть красивым, функциональность которая требует уродования кода сосет.

71201010   [re:Vlad]   15.03.2014 17:21    | Reply | Edit |
0
В ответ на:

Функция печатающая сообщение проверяет, в каких контексах она находится (динамически), и если данные контекста еще не печатались, печатает их непосредственно перед тем сообщением, которое ей передали.



как эта функция будет обращаться к сохраненному контекст? где будет храниться этот контекст?

71201010   [re:Fj_]   15.03.2014 17:27    | Reply | Edit |
0
В ответ на:

я хочу видеть в стектрейсе упавшей прожрамки значения интересных переменных. Или в эксепшене, если прожрамка упала не совсем. Причем эти переменные и их значения выводятся для всех стекфреймов в стектрейсе.



это немного другая задача, чем озвученная ТС, но все же:
code:
class MyError(Exception): def __init__(self, tr=[]): self.tr = tr def deco(f): def df(*args): try: return f(*args) except MyError,e: raise MyError(e.tr + [(f.__name__,args)]) return df # test implementation @deco def f1(a): raise MyError @deco def f2(a): f1(3) @deco def f3(a,b): f2(34) try: f3(100,500) except MyError,e: print e.tr ## -- End pasted text -- Out: [('f1', (3,)), ('f2', (34,)), ('f3', (100, 500))]


Shurik   [re:Fj_]   15.03.2014 19:21    | Reply | Edit |
2
Quote:

Код должен быть красивым, функциональность которая требует уродования кода сосет.



Тебе удается продавать этот поинт?

Top