Условие задачи:
Иногда возникает необходимость перенаправить вывод в нужное нам место, внутри программы, по ходу её выполнения. Реализуйте контекстный менеджер, который принимает два IO-объекта (например, открытые файлы) и перенаправляет туда стандартные потоки stdout и stderr.
Аргументы контекстного менеджера должны быть "непозиционными", чтобы можно было ещё перенаправить только stdout или только stderr.
И дан вот такой шаблон:
Ну собственно перенаправить stdout у меня не возникло проблемы, тут оказалось все просто, для начала открываем два файла один для stdout, второй для stderr, ну и передаём их в наш класс Redirect (исключение пока закомментил, чтобы не мозолило глаза):
Далее, переходим в класс Redirect:
Ну и при запуске программы стандартный вывод перенаправляется в файл stdout.txt, там появляется запись:
А вот подобная запись с записью ошибки в файл - не прокатывает, ошибки как нет на экране так и в файле, файл stderr.txt остается пустым, а там должна быть записана ошибка (исключение).
Прочитал снова описание методов __init__, __enter__, __exit__, и тут до меня стало доходить что ошибки как раз передаются в __exit__ и значит там нужно записывать в файл. Я специально сделал ошибку "(print( 1 / 0)" в блоке with и посмотрел что будет с переменными exc_type, exc_val, exc_tb:
А если ошибки нет, то соответственно там значения типа None:
Нужно понять как распечатать объект traceback в файл stderr.txt...
И это все были размышления в тупик...
Надо было еще раз внимательно прочитать условия задачи. И там есть строка:
Долго я мурыжился над применением этой строчки, добавлял различные аргументы в скобки а как оказалось - всё очень даже просто:
И после чего код (ниже) заработал так как это должно:
Да, забыл еще один print('Hello stdout') вписать в самом начале кода... Но это уже несущественное...
Ну вот, теперь точное соответствие с ТЗ:
Осталось сделать тесты:
- В тестах проверяется, что информация действительно была перенаправлена в другой поток вывода.
- При инициализации контекстного менеджера сохраняются предыдущие значения sys.stdout и sys.stderr. При использовании sys.__stdout__ и sys.__stderr__ могут не работать вложенные блоки.
- Учтены случаи использования контекстного менеджера без аргументов или только с одним аргументом — stdout или stderr.
Шаблон тестов:
Тесты для меня остаются "тёмным лесом" в котором я постоянно спотыкаюсь, не без помощи других студентов я таки решил эту задачу. Опять жеж тесты показали мне, что не все у меня в коде написано правильно и основной код так же пришлось корректировать. Вот из-за этого, пришлось корректировать основной код:
После корректировки основной код стал таким:
Ну и собственно сами тесты:
Собственно, особо тут ничего не нужно объяснять, все тесты это повторение основного кода с небольшими вариациями.
## Задача 5. Самопечать (выполните по желанию)
Напишите код, который выводит сам себя.
Обратите внимание, что скрипт может быть расположен в любом месте.
Задачка оказывается выполняется одной единственной строкой кода:
print(open(__file__).read())
Эту строчку можно вставить в любое место программы и она будет сама себя в консоли печатать:
Ну вот, собственно и все, этот модуль у меня оказался самым длительным по времени, ибо начинал я его еще в августе-сентябре, но там так получилось - параллельно делал курс по Django, затем диплом по Django. Который имел строгие временные рамки. И этот модуль закончил только сегодня: