Как Вы записали бы @debuggable декоратору в Python?

Вы можете попробовать это

SELECT ps.id, ps.pay_slip, ps.emp_type, COALESCE(i.employee_name, e.name) AS name 
FROM payslips ps 
LEFT JOIN internal_employee_master i ON i.id = ps.emp_id AND ps.emp_type = 'internal'
LEFT JOIN external_employee_master e ON e.id = ps.emp_id AND ps.emp_type = 'External' 
AND ps.id = :ID

Вы можете увидеть это в действии здесь http://sqlfiddle.com/#!9/53a195/7/0

[ 116] Я бы упомянул, что в ваших включенных таблицах и запросах есть ряд проблем. Например, неправильные имена столбцов между таблицами (name вместо employee_name), вы пропустили столбец is_deleted из своей примерной схемы, и у вас есть заглавные и некапитализированные значения в столбце emp_type, что сбивает с толку. [116 ]

9
задан Phil H 14 May 2009 в 15:58
поделиться

4 ответа

Используйте отладчик. Шутки в сторону. Украшать каждую функцию, которую вы хотите отслеживать, - плохая идея.

Python имеет включенный отладчик , поэтому вам не нужна хорошая IDE.

Если вы не хотите использовать отладчик, вы можете использовать функцию трассировки .

import sys

@sys.settrace
def trace_debug(frame, event, arg):
    if event == 'call':
        print ("calling %r on line %d, vars: %r" % 
                (frame.f_code.co_name, 
                 frame.f_lineno,
                 frame.f_locals))
        return trace_debug
    elif event == "return":
        print "returning", arg

def fun1(a, b):
    return a + b

print fun1(1, 2)

Это печатает:

calling 'fun1' on line 14, vars: {'a': 1, 'b': 2}
returning 3
3

Еще проще было бы использовать Winpdb :

Это платформенно-независимый графический отладчик Python GPL с поддержкой удаленной отладки по сети, нескольких потоков, модификации пространства имен, встроенной отладки, зашифрованной связи и до 20 раз быстрее, чем pdb.

Особенности:

  • Лицензия GPL. Winpdb - это бесплатное программное обеспечение.
  • Совместимо с CPython 2.3 или новее.
  • Совместимость с wxPython 2.6 или новее.
  • Независимость от платформы и тестирование на Ubuntu Gutsy и Windows XP.
  • Пользовательские интерфейсы: rpdb2 основан на консоли, тогда как winpdb требует wxPython 2.6 или новее.

Screenshot
(источник: winpdb.org )

23
ответ дан 4 December 2019 в 06:14
поделиться

Я думаю, что вам нужен не декоратор отладки, а декоратор журналирования.

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

Декоратор может выглядеть примерно так:


import logging

logger = logging.getLogger('TraceLog')
# TODO configure logger to write to file/stdout etc, it's level etc


def logthis(level):
    def _decorator(fn):
        def _decorated(*arg,**kwargs):
            logger.log(level, "calling '%s'(%r,%r)", fn.func_name, arg, kwargs)
            ret=fn(*arg,**kwargs)
            logger.log(level, "called '%s'(%r,%r) got return value: %r", fn.func_name, arg, kwargs, ret)
            return ret
        return _decorated
    return _decorator

@logthis(logging.INFO)
def myfunc(this,that):
    return this+that

Затем, если вы настроите регистратор для вывода в stderr, вы увидите:


>>> logger.setLevel(logging.INFO)
>>> handler=logging.StreamHandler()
>>> logger.addHandler(handler)
>>> myfunc(1,2)
calling 'myfunc'((1, 2),{})
called 'myfunc'((1, 2),{}) got return value: 3

11
ответ дан 4 December 2019 в 06:14
поделиться

I agree with nosklo using a debugger is much better than writing your own. I'll post an improvement to your code. But I still think you should follow nosklo's advice.

Use decorator classes to make your debugger neater:

class Debugger(object):
    enabled = False
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        if self.enabled:
            print 'Entering', self.func.func_name 
            print '    args:', args, kwargs
        return self.func(*args, **kwargs)

Debugger.enabled = True

@Debugger
def myfunc(a, b, c, d):
    pass
8
ответ дан 4 December 2019 в 06:14
поделиться

Я повторяю то, что сказал nosklo.

Еще одна вещь, на которую следует обратить внимание, - это то, что ваша функция немного опасна:

b = myfunc(1,3)

В этом случае "b" равно None , потому что декорированная функция ничего не возвращает.

0
ответ дан 4 December 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: