Найти в Дзене
Computer Pro

Модуль 5. Задача 4. Перенаправление вывода. + 5 задача

Оглавление

Условие задачи:

Иногда возникает необходимость перенаправить вывод в нужное нам место, внутри программы, по ходу её выполнения. Реализуйте контекстный менеджер, который принимает два IO-объекта (например, открытые файлы) и перенаправляет туда стандартные потоки stdout и stderr.
Аргументы контекстного менеджера должны быть "непозиционными", чтобы можно было ещё перенаправить только stdout или только stderr.

И дан вот такой шаблон:

Ну собственно перенаправить stdout у меня не возникло проблемы, тут оказалось все просто, для начала открываем два файла один для stdout, второй для stderr, ну и передаём их в наш класс Redirect (исключение пока закомментил, чтобы не мозолило глаза):

-2

Далее, переходим в класс Redirect:

-3

Ну и при запуске программы стандартный вывод перенаправляется в файл stdout.txt, там появляется запись:

-4

А вот подобная запись с записью ошибки в файл - не прокатывает, ошибки как нет на экране так и в файле, файл stderr.txt остается пустым, а там должна быть записана ошибка (исключение).

Прочитал снова описание методов __init__, __enter__, __exit__, и тут до меня стало доходить что ошибки как раз передаются в __exit__ и значит там нужно записывать в файл. Я специально сделал ошибку "(print( 1 / 0)" в блоке with и посмотрел что будет с переменными exc_type, exc_val, exc_tb:

-5

А если ошибки нет, то соответственно там значения типа None:

-6

Нужно понять как распечатать объект traceback в файл stderr.txt...

И это все были размышления в тупик...

Надо было еще раз внимательно прочитать условия задачи. И там есть строка:

-7

Долго я мурыжился над применением этой строчки, добавлял различные аргументы в скобки а как оказалось - всё очень даже просто:

-8

И после чего код (ниже) заработал так как это должно:

То что в блоке with записывается в соответствующие файлы, а остальное - выдается на экран.
То что в блоке with записывается в соответствующие файлы, а остальное - выдается на экран.
-10
-11
-12

Да, забыл еще один print('Hello stdout') вписать в самом начале кода... Но это уже несущественное...

Ну вот, теперь точное соответствие с ТЗ:

-13

Осталось сделать тесты:

  • В тестах проверяется, что информация действительно была перенаправлена в другой поток вывода.
  • При инициализации контекстного менеджера сохраняются предыдущие значения sys.stdout и sys.stderr. При использовании sys.__stdout__ и sys.__stderr__ могут не работать вложенные блоки.
  • Учтены случаи использования контекстного менеджера без аргументов или только с одним аргументом — stdout или stderr.

Шаблон тестов:

-14

Тесты для меня остаются "тёмным лесом" в котором я постоянно спотыкаюсь, не без помощи других студентов я таки решил эту задачу. Опять жеж тесты показали мне, что не все у меня в коде написано правильно и основной код так же пришлось корректировать. Вот из-за этого, пришлось корректировать основной код:

-15

После корректировки основной код стал таким:

-16
-17

Ну и собственно сами тесты:

-18
-19
-20

Собственно, особо тут ничего не нужно объяснять, все тесты это повторение основного кода с небольшими вариациями.

## Задача 5. Самопечать (выполните по желанию)

Напишите код, который выводит сам себя.
Обратите внимание, что скрипт может быть расположен в любом месте.

Задачка оказывается выполняется одной единственной строкой кода:

print(open(__file__).read())

Эту строчку можно вставить в любое место программы и она будет сама себя в консоли печатать:

-21

Ну вот, собственно и все, этот модуль у меня оказался самым длительным по времени, ибо начинал я его еще в августе-сентябре, но там так получилось - параллельно делал курс по Django, затем диплом по Django. Который имел строгие временные рамки. И этот модуль закончил только сегодня:

-22