Контекст отладочных сообщений
я так понял ты решил переизобрести MDC/NDC?
Похоже что да. А NDC умеет печататься как у меня в примере, или только тупо
?
in the context bicycleproblem with the wheelin the context bicycleprobelm with the wheelin the context bicycleproblem with the wheelhr />
?
Это уже от appender-а зависит, если он умеет не выводить повторяющийся контекст дважды, то почему бы и нет? Ну а вообще если у нас несколько потоков и в лог не выводится id потока, то такая оптимизация может выйти боком.
Я об этой проблеме много думал.
Я думал о ней так: я хочу видеть в стектрейсе упавшей прожрамки значения интересных переменных. Или в эксепшене, если прожрамка упала не совсем. Причём эти переменные и их значения выводятся для всех стекфреймов в стектрейсе.
Твоё решение мне в общем нравится, но только оно будет приводить к сильно повышенному нестингу. Вот если б я это писал на плюсах, решение было бы довольно очевидным: взять макрос для уникального имени переменной ("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" без дичайших извращений?
Я думал о ней так: я хочу видеть в стектрейсе упавшей прожрамки значения интересных переменных. Или в эксепшене, если прожрамка упала не совсем. Причём эти переменные и их значения выводятся для всех стекфреймов в стектрейсе.
Твоё решение мне в общем нравится, но только оно будет приводить к сильно повышенному нестингу. Вот если б я это писал на плюсах, решение было бы довольно очевидным: взять макрос для уникального имени переменной ("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" без дичайших извращений?
В с++ прикольно получается!
Я бы предпочёл группировать переменные по domain specific фреймам, а не получать их длинным однородным списком, но это тоже легко делается добавлением ещё одной raii-штуки.
Но что именно тебя в питоне смущает, что надо в четыре пробела отступ делать после with? Так это же не на каждую отладочную переменную, а на каждый контекст только.
Ну и в любом случае можно так:
Я бы предпочёл группировать переменные по domain specific фреймам, а не получать их длинным однородным списком, но это тоже легко делается добавлением ещё одной raii-штуки.
Но что именно тебя в питоне смущает, что надо в четыре пробела отступ делать после with? Так это же не на каждую отладочную переменную, а на каждый контекст только.
Ну и в любом случае можно так:
@interesting_pseudo_frame
def process_bicycle(bicycle):
interesting_value("bicycle.id", bicycle.id)
...
Эм, а как ты это сделаешь, interesting_value динамически не появится в обёрнутой функции. Или ты совсем кривой хак имеешь в виду?
Но это навело меня на мысль кстати, что наверное хочется обычно сохранять именно значения аргументов функции (ибо если кому нужно вычисленное сохранить — пусть сохраняет в вызываемой функции). И вот тут вполне уместно сделать декоратор который их сохраняет. В третьем питоне (я не знаю, его нормальные люди уже используют?) можно даже как бы теги добавлять к аргументам.
> Но что именно тебя в питоне смущает, что надо в четыре пробела отступ делать после with?
Да, дико смущает. Код должен быть красивым, функциональность которая требует уродования кода сосёт.
Но это навело меня на мысль кстати, что наверное хочется обычно сохранять именно значения аргументов функции (ибо если кому нужно вычисленное сохранить — пусть сохраняет в вызываемой функции). И вот тут вполне уместно сделать декоратор который их сохраняет. В третьем питоне (я не знаю, его нормальные люди уже используют?) можно даже как бы теги добавлять к аргументам.
> Но что именно тебя в питоне смущает, что надо в четыре пробела отступ делать после with?
Да, дико смущает. Код должен быть красивым, функциональность которая требует уродования кода сосёт.
Функция печатающая сообщение проверяет, в каких контексах она находится (динамически и если данные контекста ещё не печатались, печатает их непосредственно перед тем сообщением, которое ей передали.как эта функция будет обращаться к сохраненному контекст? где будет храниться этот контекст?
я хочу видеть в стектрейсе упавшей прожрамки значения интересных переменных. Или в эксепшене, если прожрамка упала не совсем. Причём эти переменные и их значения выводятся для всех стекфреймов в стектрейсе.это немного другая задача, чем озвученная ТС, но все же:
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]
Код должен быть красивым, функциональность которая требует уродования кода сосёт.Тебе удается продавать этот поинт?
Оставить комментарий
Dmitriy82
Допустим, есть такой код:Неудобство в том, что напечатается проблематичное колесо, но не будет понятно к какому велосипеду оно относится.
Что можно сделать?
Можно всегда печатать текущий велосипед. Но их может быть много.
Можно передавать велосипед дополнительным аргументом в process_wheel, но это как-то мерзко потому что он нужен исключительно в отладочных целях.
Можно сделать process_wheel методом класс BicycleProcessor, у которого в состоянии есть current_bicycle. Но это ООП.
Вдобавок, недостаток последних двух подходов в том, что колёса бывают не только у велосипедов.
Мне недавно пришла в голову такая идея. Ввести контекст-менеждер, который будет содержать отладочный, хм, контекст. Функция печатающая сообщение проверяет, в каких контексах она находится (динамически и если данные контекста ещё не печатались, печатает их непосредственно перед тем сообщением, которое ей передали.
Типа, код будет выглядеть так:
А печатать будет примерно следующее:
Бонус: контексты могут быть вложенными.
Получаются типа такие domain-specific stack traces.
---
Никакого вопроса тут нет, просто решил поделиться.