Форум сайта python.su
0
doza_andТем, что он не корректно работает в PyScripter, точнее PyScripter криво работает с ним. Я уже к этой среде разработки привык, и для данной задачи мне достаточно просто дублирования консоли в лог-файл. Больше ничего не требуется.
1 Чем этот велосипед лучше модуля logging?
doza_andА как еще убедиться, что файловой переменной соответствует файл? А вдруг не удалось в самом начале файл создать?
2. Зачем при каждой записи делается проверка?
doza_andВот этот момент меня тоже смущает пока. Приложение может работать часами и, если не сохранять в файл, то оно будет потиху отжирать оперативу.
Какповлияет на производительность вашей системы записи логов?logfile.flush()
doza_andУ меня только консоль, и она всегда видна.
4. Почему вы заловили все Exception и вместо них вывели сообщения в консоль (которой часто у приложения просто нет или ее не видно)?
doza_andПока работает отлично. С загрузкой процессора при данном варианте пока не выяснял.
5. Как приведенный скрипт решает поставленную вами задачу об одновременном выводе в консоль и файл?
Офлайн
20
Я тоже подискутирую, с вашего позволения :-).
2. Зачем logfile is None? А почему нет, какие ещё варианты? С точки зрения снижения производительности тут нет никакого существенного снижения, особенно на фоне операций `strftime`, выполнения print и записи в stdout и в файл. Да и с учётом выбранного условного объёма в 10000 записей, который ни о чём эта операция никак не может повлиять ни на общую производительность приложения, ни даже на отдельно взятую функцию логирования.
Другой аргумент за такой подход, это включение всего функционала по логированию в одну функцию, а не размазывание по нескольким: открытие, логирование, закрытие :-). Если бы использовался класс, то открытие файла можно было бы вынести в отдельный приватный метод или в __init__ экземпляра и выполнять его один раз при создании экземпляра. А как иначе выполнить инкапсуляцию (сокрыть открытие файла от основного кода) без ООП в данном случае, я не знаю.
3. `logfile.flush` не должен влиять на производительность, по крайней мере положительно. Отрицательное влияние если и есть, то оно не существенно. О памяти здесь переживать не стоит, буфер используется небольшой 16kb или 64kb. Кажется Python сам ничего не буферизует, так что после `write` данные передаются ОС и можно не волноваться за то что они попадут куда следует.
4. Ошибки при обработке ошибок больная тема :-). Так что такие обработчики не то что бы совсем лишены смысла. Открытие действительно может не получиться. Запись тоже, скорее всего только из-за закрытого дескриптора. Но помимо записи о самом факте ошибке, не помешало бы ещё написать подробности о ней: тип и сообщение …Exception as exc: …' {}'.format(type(exc).__name__, exc)…. В случае ошибки записи не помешает что-то такое:
if not logfile.closed: logfile.close() logfile = None
Офлайн
0
bwДа, ступил. При первом вызове откроется только файл, а в него ничего не будет записано.
Что там за `else`? Автор пробовал выполнить алгоритм в уме? Что у него получилось в случае `logfile is None`?
def printlog(*args): """ Подпрограмма одновременного вывода строки на экран и в файл """ global logfile t = time.strftime("%H:%M:%S") + " " print (t, *args) if logfile is None: try: logfile = open(LOGFILE, 'a') except Exception: print (t, "Не могу открыть лог-файл") return try: print(t, *args, file = logfile) logfile.flush() except Exception: print (t, "Не могу добавить строку в лог-файл")
Офлайн
253
admiral
Тем, что он не корректно работает в PyScripter
import logging import sys logger = logging.getLogger('simple_example') logger.setLevel(logging.DEBUG) # create file handler which logs even debug messages fh = logging.FileHandler('spam.log') fh.setLevel(logging.DEBUG) # create console handler with a higher log level ch = logging.StreamHandler() ch.setLevel(logging.ERROR) # create formatter and add it to the handlers formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) fh.setFormatter(formatter) # add the handlers to logger logger.addHandler(ch) logger.addHandler(fh) # 'application' code logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message')
Отредактировано doza_and (Янв. 5, 2014 14:37:52)
Офлайн
0
Спасибо. Такой код действительно заработал.
Буду использовать logging.
Офлайн