Ввод-вывод ========== Рано или поздно возникают ситуации, когда программа должна взаимодействовать с пользователем. Например, принять какие-нибудь данные от пользователя, а затем вывести результаты. Для этого применяются функции ``input()`` и ``print()`` соответственно. Для вывода можно также использовать различные методы класса ``str`` (строка). К примеру, при помощи метода ``rjust`` можно получить строку, выравненную по правому краю к указанной ширине. См. ``help(str)`` для более подробного описания. Ещё одним распространённым типом ввода/вывода является работа с файлами. Возможность создавать, читать и записывать в файлы является ключевой для многих программ, поэтому в настоящей главе и мы рассмотрим этот аспект. Ввод от пользователя -------------------- Сохраните эту программу как ``user_input.py``: .. sourcecode:: python def reverse(text): return text[::-1] def is_palindrome(text): return text == reverse(text) something = input('Введите текст: ') if (is_palindrome(something)): print("Да, это палиндром") else: print("Нет, это не палиндром") **Вывод:** :: $ python3 user_input.py Введите текст: сэр Нет, это не палиндром $ python3 user_input.py Введите текст: мадам Да, это палиндром $ python3 user_input.py Введите текст: топот Да, это палиндром **Как это работает:** Мы применяем операцию вырезки для переворачивания текста. Мы уже видели, как создаются :ref:`вырезки из последовательностей ` при помощи кода "``seq[a:b]``", начиная с позиции ``a`` до позиции ``b``. Но ведь мы также можем указать и третий аргумент, определяющий *шаг*, с которым производится вырезка. По умолчанию шаг равен ``1``, поэтому и возвращается непрерывный фрагмент текста. Указание отрицательного шага, т.е. ``-1`` приведёт к выводу текста в обратном порядке. Функция ``input()`` принимает строку в качестве аргумента и показывает её пользователю. Затем она ждёт, чтобы пользователь набрал что-нибудь и нажал клавишу ввода. Как только пользователь это сделал, функция ``input()`` возвращает введённый пользователем текст. Мы считываем этот текст и выстраиваем его в обратном порядке. Если перевёрнутый и исходный текст одинаковы, значит введённый текст является `палиндромом `_. .. admonition:: **Домашнее задание** Проверка, является ли текст палиндромом должна также игнорировать знаки пунктуации, пробелы и регистр букв. Например, "А роза упала на лапу Азора" также является палиндромом, но наша текущая программа так не считает. Попробуйте улучшить её так, чтобы она распознала этот палиндром. .. hint:: **(не читайте)** Воспользуйтесь кортежем (список *всех* знаков пунктуации можно найти `здесь `_), содержащим все запрещённые символы, и примените тест на принадлежность, чтобы обнаружить символы, подлежащие удалению, т.е. forbidden = ('!', '?', '.', ...). Файлы ----- Открывать и использовать файлы для чтения или записи можно путём создания объекта класса ``file``, а читать/записывать в файл -- при помощи его методов ``read``, ``readline`` или ``write`` соответственно. Возможность читать или записывать в файл зависит от режима, указанного при открытии файла. По окончании работы с файлом, нужно вызвать метод ``close``\ [1]_, чтобы указать Python, что файл больше не используется. **Пример:** (сохраните как ``using_file.py``) .. sourcecode:: python poem = '''\ Программировать весело. Если работа скучна, Чтобы придать ей весёлый тон - используй Python! ''' f = open('poem.txt', 'w') # открываем для записи (writing) f.write(poem) # записываем текст в файл f.close() # закрываем файл f = open('poem.txt') # если не указан режим, по умолчанию подразумевается # режим чтения ('r'eading) while True: line = f.readline() if len(line) == 0: # Нулевая длина обозначает конец файла (EOF) break print(line, end='') f.close() # закрываем файл **Вывод:** :: $ python3 using_file.py Программировать весело. Если работа скучна, Чтобы придать ей весёлый тон - используй Python! **Как это работает:** Сперва мы открываем файл при помощи встроенной функции ``open`` с указанием имени файла и режима, в котором мы хотим его открыть. Режим может быть для чтения (``'r'``), записи (``'w'``) или добавления (``'a'``)\ [2]_. Можно также указать, в каком виде мы будем считывать, записывать или добавлять данные: в текстовом (``'t'``) или бинарном (``'b'``). На самом деле существует много других режимов, и ``help(open)`` даст вам их детальное описание. По умолчанию ``open()`` открывает файл как текст в режиме для чтения. В нашем примере мы сначала открываем файл в режиме записи текста и используем метод ``write`` файлового объекта для записи в файл, после чего закрываем файл при помощи ``close``. Далее мы открываем тот же самый файл для чтения. В этом случае нет нужды указывать режим, так как режим "чтения текстового файла" применяется по умолчанию. Мы считываем файл построчно методом ``readline`` в цикле. Этот метод возвращает полную строку, включая символ перевода строки в конце. Когда же он возвращает пустую строку, это означает, что мы достигли конца файла, и мы прерываем цикл при помощи ``break``. По умолчанию функция ``print()`` выводит текст, автоматически добавляя символ перевода строки в конце. Мы подавляем этот символ, указывая ``end=''``, поскольку строки, считанные из файла, и без того оканчиваются символом перевода строки. И, наконец, мы закрываем файл с помощью ``close``. Теперь проверяем содержимое файла ``poem.txt``, чтобы убедиться, что программа действительно записала текст в него и считала из него. Pickle ------ Python предоставляет стандартный модуль с именем ``pickle``\ [3]_, при помощи которого можно сохранять **любой** объект Python в файле, а затем извлекать его обратно. Это называется *длительным* хранением объекта. **Пример:** (сохраните как ``pickling.py``): .. sourcecode:: python import pickle # имя файла, в котором мы сохраним объект shoplistfile = 'shoplist.data' # список покупок shoplist = ['яблоки', 'манго', 'морковь'] # Запись в файл f = open(shoplistfile, 'wb') pickle.dump(shoplist, f) # помещаем объект в файл f.close() del shoplist # уничтожаем переменную shoplist # Считываем из хранилища f = open(shoplistfile, 'rb') storedlist = pickle.load(f) # загружаем объект из файла print(storedlist) **Вывод:** :: $ python3 pickling.py ['яблоки', 'манго', 'морковь'] **Как это работает:** Чтобы сохранить объект в файле, нам нужно сперва открыть файл с помощью ``open`` в режиме бинарной записи (``'wb'``), после чего вызвать функцию ``dump`` из модуля ``pickle``. Этот процесс называется "консервацией" ("pickling"). После этого мы извлекаем объект при помощи функции ``load`` из модуля ``pickle``, которая возвращает объект. Этот процесс называется "расконсервацией" ("unpickling"). Резюме ------ Мы обсудили разные типы ввода/вывода, а также работу с файлами и использование модуля ``pickle``. Далее мы познакомимся с концепцией исключений. Примечания ---------- .. [1] close -- *англ.* "закрывать" (*прим.перев*) .. [2] **r**\ ead, **w**\ rite и **a**\ ppend соответственно (*прим.перев.*) .. [3] pickle -- *англ.* "мариновать", "солить" (*прим.перев.*)