#python #logging #input #console
#питон #регистрация #вход #приставка
Вопрос:
Я новичок в python. Я столкнулся с незначительной проблемой в выводе моей консоли при использовании вывода StreamHandler() из модуля ведения журнала вместе со строкой ввода ().
Я настраиваю свой регистратор со следующей функцией:
def configure_logger(filename='log'): """Configures a logger which outputs at level INFO and above to both the console and a file called 'filename'. """ file_handler = logging.FileHandler(filename, mode='w') stream_handler = logging.StreamHandler() file_formatter = logging.Formatter(datefmt="%d/%m/%Y %H:%M:%S", fmt='%(levelname)-8s %(asctime)s ' '%(name)-50s - %(message)s') stream_formatter = logging.Formatter(fmt='%(levelname)-8s %(name)-50s - ' '%(message)s') file_handler.setFormatter(file_formatter) stream_handler.setFormatter(stream_formatter) logging.basicConfig(handlers=(file_handler, stream_handler), level=logging.INFO)
Позже я вызываю следующую функцию дважды подряд, чтобы создать два каталога:
def create_directory(directory): """Creates a directory, prompting the user to confirm overwrite if it already exists """ logger = logging.getLogger(f'{__name__}.create_directory') logger.info(f'Creating directory {directory}') try: os.mkdir(directory) except FileExistsError: overwrite = input(f'Directory {directory} already ' f'exists. Overwrite? (y/n): ') overwrite.lower() while overwrite not in ['y', 'yes', 'n', 'no']: overwrite = input(f'Enter yes/y or no/n?: ') overwrite.lower() if overwrite in ['y', 'yes']: logger.warning('Overwriting existing directory') shutil.rmtree(directory) os.mkdir(directory) else: logger.info("Exiting") sys.exit()
Если каталог, который я пытаюсь создать, уже существует, я запрашиваю пользователя и прошу его подтвердить, что он хочет перезаписать его с помощью функции ввода (). После ответа » да «я регистрирую предупреждение » Перезапись существующего каталога».
После вызова create_directory() дважды подряд я получаю следующее в своей консоли:
INFO sowfatools.create_directory - Creating directory time_histories Directory time_histories already exists. Overwrite? (y/n): gt;? y Directory time_history_plots already exists. Overwrite? (y/n): WARNING sowfatools.create_directory - Overwriting existing directory INFO sowfatools.create_directory - Creating directory time_history_plots gt;?
Вторая строка ввода (которая поступает из второго вызова функции) выводится на консоль ПЕРЕД предупреждением от первого вызова функции. На самом деле это происходит и ПЕРЕД первым сообщением о регистрации во втором вызове.
Почему это может быть? и как мне это исправить? Это не делает мой код непригодным для использования, но это неприятно. Является ли обработчик потока ведения журнала слишком медленным, чтобы идти в ногу с остальной частью кода? Кроме того, поскольку я новичок в этом, любые другие отзывы о том, как я делаю, приветствуются.
Спасибо!
Ответ №1:
input
записывает свои запросы в stdout, а ведение журнала переходит в stderr. Эти два потока независимы и могут непредсказуемо чередоваться.
Любой:
- Замените ведение журнала вызовов на
print
, - Настройте ведение журнала так, чтобы оно переходило в stdout вместо stderr, или
- Замените
input(prompt)
наprint(prompt, file=sys.stderr, end=''); input()
в многоразовой функции.
Комментарии:
1. Блестяще, спасибо! Я решил изменить вывод своего регистратора на stdout, используя
stream_handler = logging.StreamHandler(stream=sys.stdout)
в своейconfigure_logger()
функции. Это подействовало очаровательно.