Взаимодействие консоли Python между обработчиком потока для ведения журнала() и входом()

#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. Эти два потока независимы и могут непредсказуемо чередоваться.

Любой:

  1. Замените ведение журнала вызовов на print ,
  2. Настройте ведение журнала так, чтобы оно переходило в stdout вместо stderr, или
  3. Замените input(prompt) на print(prompt, file=sys.stderr, end=''); input() в многоразовой функции.

Комментарии:

1. Блестяще, спасибо! Я решил изменить вывод своего регистратора на stdout, используя stream_handler = logging.StreamHandler(stream=sys.stdout) в своей configure_logger() функции. Это подействовало очаровательно.