Контекст отладочных сообщений
я так понял ты решил переизобрести MDC/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" без дичайших извращений?
Я бы предпочёл группировать переменные по domain specific фреймам, а не получать их длинным однородным списком, но это тоже легко делается добавлением ещё одной raii-штуки.
Но что именно тебя в питоне смущает, что надо в четыре пробела отступ делать после with? Так это же не на каждую отладочную переменную, а на каждый контекст только.
Ну и в любом случае можно так:
@interesting_pseudo_frame
def process_bicycle(bicycle):
interesting_value("bicycle.id", bicycle.id)
...
Но это навело меня на мысль кстати, что наверное хочется обычно сохранять именно значения аргументов функции (ибо если кому нужно вычисленное сохранить — пусть сохраняет в вызываемой функции). И вот тут вполне уместно сделать декоратор который их сохраняет. В третьем питоне (я не знаю, его нормальные люди уже используют?) можно даже как бы теги добавлять к аргументам.
> Но что именно тебя в питоне смущает, что надо в четыре пробела отступ делать после 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.
---
Никакого вопроса тут нет, просто решил поделиться.