# Ввод-вывод

Рано или поздно возникают ситуации, когда программа должна взаимодействовать с пользователем. Например, принять какие-нибудь данные от пользователя, а затем вывести результаты. Для этого применяются функции `input()` и `print()` соответственно.

Для вывода можно также использовать различные методы класса `str` (строка). К примеру, при помощи метода `rjust` можно получить строку, выравненную по правому краю к указанной ширине. См. `help(str)` для более подробного описания.

Ещё одним распространённым типом ввода/вывода является работа с файлами. Возможность создавать, читать и записывать в файлы является ключевой для многих программ, поэтому в настоящей главе и мы рассмотрим этот аспект.

### Ввод от пользователя

Сохраните эту программу как `user_input.py`:

```python
def reverse(text):
    return text[::-1]

def is_palindrome(text):
    return text == reverse(text)

something = input('Введите текст: ')
if (is_palindrome(something)):
    print("Да, это палиндром")
else:
    print("Нет, это не палиндром")
```

**Вывод:**

```python
$ python3 user_input.py
Введите текст: сэр
Нет, это не палиндром

$ python3 user_input.py
Введите текст: мадам
Да, это палиндром

$ python3 user_input.py
Введите текст: топот
Да, это палиндром
```

**Как это работает:**

> Функция `input()` принимает строку в качестве аргумента и показывает её пользователю. Затем она ждёт, чтобы пользователь набрал что-нибудь и нажал клавишу ввода. Как только пользователь это сделал, функция `input()` возвращает введённый пользователем текст.
>
> Мы считываем этот текст и выстраиваем его в обратном порядке. Если перевёрнутый и исходный текст одинаковы, значит введённый текст является [палиндромом](http://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D0%BB%D0%B8%D0%BD%D0%B4%D1%80%D0%BE%D0%BC).

### Файлы

Открывать и использовать файлы для чтения или записи можно путём создания объекта класса `file`, а читать/записывать в файл – при помощи его методов `read`, `readline` или `write` соответственно. Возможность читать или записывать в файл зависит от режима, указанного при открытии файла. По окончании работы с файлом, нужно вызвать метод `close`, чтобы указать Python, что файл больше не используется.

**Пример:** (сохраните как `using_file.py`)

```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() # закрываем файл
```

**Вывод:**

```python
$ python3 using_file.py
Программировать весело.
Если работа скучна,
Чтобы придать ей весёлый тон -
    используй Python!
```

**Как это работает:**

> Сперва мы открываем файл при помощи встроенной функции `open` с указанием имени файла и режима, в котором мы хотим его открыть. Режим может быть для чтения (`'r'`), записи (`'w'`) или добавления (`'a'`). Можно также указать, в каком виде мы будем считывать, записывать или добавлять данные: в текстовом (`'t'`) или бинарном (`'b'`). На самом деле существует много других режимов, и `help(open)` даст вам их детальное описание. По умолчанию `open()` открывает файл как текст в режиме для чтения.
>
> В нашем примере мы сначала открываем файл в режиме записи текста и используем метод `write` файлового объекта для записи в файл, после чего закрываем файл при помощи `close`.
>
> Далее мы открываем тот же самый файл для чтения. В этом случае нет нужды указывать режим, так как режим “чтения текстового файла” применяется по умолчанию. Мы считываем файл построчно методом `readline` в цикле. Этот метод возвращает полную строку, включая символ перевода строки в конце. Когда же он возвращает пустую строку, это означает, что мы достигли конца файла, и мы прерываем цикл при помощи `break`.
>
> По умолчанию функция `print()` выводит текст, автоматически добавляя символ перевода строки в конце. Мы подавляем этот символ, указывая `end=''`, поскольку строки, считанные из файла, и без того оканчиваются символом перевода строки. И, наконец, мы закрываем файл с помощью `close`.
>
> Теперь проверяем содержимое файла `poem.txt`, чтобы убедиться, что программа действительно записала текст в него и считала из него.

### Pickle

Python предоставляет стандартный модуль с именем `pickle`, при помощи которого можно сохранять **любой** объект Python в файле, а затем извлекать его обратно. Это называется *длительным* хранением объекта.

**Пример:** (сохраните как `pickling.py`):

```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)
```

**Вывод:**

```python
$ python3 pickling.py
['яблоки', 'манго', 'морковь']
```

**Как это работает:**

> Чтобы сохранить объект в файле, нам нужно сперва открыть файл с помощью `open` в режиме бинарной записи (`'wb'`), после чего вызвать функцию `dump` из модуля `pickle`. Этот процесс называется “консервацией” (“pickling”).
>
> После этого мы извлекаем объект при помощи функции `load` из модуля `pickle`, которая возвращает объект. Этот процесс называется “расконсервацией” (“unpickling”).
