Самое первое, что нужно делать в любом более-менее полезном скрипте или большой программе - это настроить логирование.
В самом простейшем виде его можно устроить так:
import sys
import logging
if __name__ == '__main__':
log = logging.getLogger()
log.level = logging.DEBUG
log.addHandler(logging.StreamHandler(sys.stderr))
else:
log = logging.getLogger(__name__)
## Используем так:
log.info('any text')
log.debug('Something about %r in %s', log, __name__)
## Здесь размещаем весь остальной код
if __name__ == '__main__':
pass # А здесь, если надо, размещаем то, что будет выполняться, когда модуль запускают как скрипт
Тут всё логирование заворачивается в sys.stderr, не настроено форматирование, вывод в файл и ротация. Это минимальный уровень, дающий возможность отказаться от print для логирования.
Пример для питона 2.7.
Добавлю, что при непосредственном запуске этого кода логгер создаётся с именем по умолчанию (root). Это значит, что в других модулях проекта, управление которым передаётся,
log = logging.getLogger(__name__)
создаст логгер с именем модуля, и в главном файле можно будет настроить роутинг логов с учетом этих имён.
Роутинг настраивается добавлением дополнительных хендлеров и к ним разных фильтров. Если есть какие-то затруднения с этим - пишите, поясню.
Использовать правильное управляемое, расширяемое и гибкое логирование вместо россыпи принтов очень просто. Нужно просто себя приучить к этому, как к чему-то обязательному вроде чистки зубов, использования системы контроля версий и своевременного бэкапа.