1. Python / Говнокод #12135

    −100

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    import traceback
    
    class Watcher(object):
        def __init__(self, obj=None, attr=None, log_file='log.txt', include=[], enabled=False):
            """
                Debugger that watches for changes in object attributes
                obj - object to be watched
                attr - string, name of attribute
                log_file - string, where to write output
                include - list of strings, debug files only in these directories.
                   Set it to path of your project otherwise it will take long time
                   to run on big libraries import and usage.
            """
    
            self.log_file=log_file
            with open(self.log_file, 'wb'): pass
            self.prev_st = None
            self.include = [incl.replace('\\','/') for incl in include]
            if obj:
                self.value = getattr(obj, attr)
            self.obj = obj
            self.attr = attr
            self.enabled = enabled # Important, must be last line on __init__.
    
        def __call__(self, *args, **kwargs):
            kwargs['enabled'] = True
            self.__init__(*args, **kwargs)
    
        def check_condition(self):
            tmp = getattr(self.obj, self.attr)
            result = tmp != self.value
            self.value = tmp
            return result
    
        def trace_command(self, frame, event, arg):
            if event!='line' or not self.enabled:
                return self.trace_command
            if self.check_condition:
                if self.prev_st:
                    with open(self.log_file, 'ab') as f:
                        print >>f, "Value of",self.obj,".",self.attr,"changed!"
                        print >>f,"###### Line:"
                        print >>f,''.join(self.prev_st)
            if self.include:
                fname = frame.f_code.co_filename.replace('\\','/')
                to_include = False
                for incl in self.include:
                    if fname.startswith(incl):
                        to_include = True
                        break
                if not to_include:
                    return self.trace_command
            self.prev_st = traceback.format_stack(frame)
            return self.trace_command
    import sys
    watcher = Watcher()
    sys.settrace(watcher.trace_command)

    Говнокод. А ваш стиральный порошок хаскель умеет сам себя дебажить?

    Запостил: serpinski, 16 Ноября 2012

    Комментарии (17) RSS

    • Наш хаскель умеет себя дебажать, отлаживать, на нем даже компилятор (умеет компилировать) и иде написаны.
      Ответить
      • И сервер игры про ёжиков.

        Ты не знаешь, что такое ад зависимостей? Тогда собери hedge wars! Только здесь гуй перед игрой на qt, движок на паскале с sdl, а сервер на хаскеле.
        Ответить
        • Это реально такой проект есть?
          Ответить
          • http://www.hedgewars.org
            Но что-то он сегодня дохлый.
            Ответить
            • А фишка в том, чтобы каждую часть написать на не самом подходящем для неё языке?
              Ответить
            • Я играл. Это треш и содомия.
              Ответить
            • Хм. Первый раз вижу минус за ссылку. Причем я же предупредил, что сегодня она не открывается ;)
              Ответить
              • Надо было по значению передавать.
                Ответить
    • def __call__(self, *args, **kwargs):
              kwargs['enabled'] = True
              self.__init__(*args, **kwargs)


      Говным-говно...
      Ответить
      • А как надо?
        Ответить
        • __init__() - это конструктор, его вообще лучше вручную не дергать. Вряд ли что-то скверное произойдет, но сбивает с толку.
          Надо сбросить состояние объекта в нескольких местах - вынеси в отдельный не-магический метод с осмысленным названием, и вызывай его.
          Ответить
          • __init__() - это не конструктор, это инициализатор, он нового обьекта не возвращает. Если нужен именно свежий обьект, лучше его и сделать. Небольшой оверхед не стоит ебаного гимора, если забудешь где-то что-то сбросить
            Ответить
        • Наверно, return Watcher(). Действительно, как?
          Ответить
      • > *args, **kwargs

        Агрс кваргс шмаргс.
        Ответить
    • Я использую inspect, для того чтобы пройтись по фреймам и записать в лог, откуда вызвана функция логирования. Всё потому, что мне не понравился синтаксис стандартных функций из logging. Сам воспринимаю это примерно как блэккодинг с ассемблерными вставками в бейсике:))
      Ответить
    • def __init__(include=[])

      Категорически не надо использовать в качестве значения по умолчанию изменяемый обьект, т.к. он будет синглтоном.
      Ответить

    Добавить комментарий