Ввод и вывод

Есть несколько способов представить результаты программы; данные могут быть напечатаны в удобочитаемой форме или записаны в файл для дальнейшего использования. В этом уроке мы разберем это

Форматирование вывода

До сих пор мы сталкивались с 2 способами записи значений: выражения и функция print(). Но сегодня мы изучим третий способ: с помощью функции write().

Очень часто нам нужно контроллировать вывод, чем просто выводить значения, разделенные пробелами. Есть несколько способов форматирования вывода:

  • Поставьте f или F перед кавычками, чтобы мы могли легко записывать различные выражения, использую фигурные скобки. Это намного удобнее и избавляет вас от кучи плюсов.
>>> year = 2016
>>> event = 'Referendum'
>>> f'Results of the {year} {event}'
'Results of the 2016 Referendum'
  • Вы можете использовать метод str.format(). Он делает примерно тоже самое, но все это делается после сроки в отдельной функции:
>>> yes_votes = 42_572_654
>>> no_votes = 43_132_495
>>> percentage = yes_votes / (yes_votes + no_votes)
>>> '{} YES votes  {}'.format(yes_votes, percentage)
' 42572654 YES votes  49.67%'
  • И наконец вы можете использовать операции среза, конкатенации и объединения строк. Но кому это вообще нужно?

Также вы можете преобразовать любое значение в строку с помощью функций repr() или str().

str() преобразовывает в строку и форматирует эту строку, удаляя спецсимволы и кавычки. А repr() же делает наоборот. Он осталяет спецсиволы и кавычки. Вот пример:

>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> repr(s)
"'Hello, world.'"
>>> str(1/7)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'
>>> print(s)
The value of x is 32.5, and y is 40000...
>>> # Функция repe() оставляет спеццсимволы и кавычки
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, world\n'
>>> # Аргументами фунцкии repe() может быть люьой объект python
... repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam', 'eggs'))"

Форматированные строковые литералы

Отформатированные строковые литералы (также называемые f-строками для краткости) позволяют вам включать значение выражений Python в строку, добавляя к строке префиксfили илиFи записывая выражения.

Необязательный спецификатор формата может следовать за выражением. Это позволяет лучше контролировать форматирование значения. Следующий пример округляет число до десяти после десятичного числа:

>>> import math
>>> print(f'The value of pi is approximately {math.pi:.3f}.')
The value of pi is approximately 3.142.

Передача целого числа после ':'символа приведет к минимальному количеству символов в этом поле. Это полезно для выравнивания столбцов:

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
...     print(f'{name:10} ==> {phone:10d}')
...
Sjoerd     ==>       4127
Jack       ==>       4098
Dcab       ==>       7678

Другие модификаторы могут использоваться для преобразования значения до его форматирования. '!a' применяет ascii(), '!s' применяет str() и '!r' применяет repr():

>>> animals = 'eels'
>>> print(f'My hovercraft is full of {animals}.')
My hovercraft is full of eels.
>>> print(f'My hovercraft is full of {animals!r}.')
My hovercraft is full of 'eels'.

Строковвой метод format()

Основное использование str.format() метода выглядит следующим образом:

>>> print('We are the {} who say "{}!"'.format('knights', 'Ni'))
We are the knights who say "Ni!"

Скобки и символы внутри них (называемые полями формата) заменяются объектами, переданными в str.format() метод. Число в скобках может быть использовано для обозначения позиции объекта, переданного в str.format():

>>> print('{0} and {1}'.format('spam', 'eggs'))
spam and eggs
>>> print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam

Если в str.format() методе используются ключевые аргументы, на их значения ссылается имя аргумента.

>>> print('This {food} is {adjective}.'.format(
...       food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.

Позиционные и ключевые аргументы могут быть произвольно объединены:

>>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',
                                                       other='Georg'))
The story of Bill, Manfred, and Georg.

Если у вас действительно длинная строка формата, которую вы не хотите разделять, было бы хорошо, если бы вы могли ссылаться на переменные, которые должны быть отформатированы по имени, а не по позиции. Это можно сделать, просто передав диктовку и используя квадратные скобки '[]'для доступа к ключам.

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {0[Jack]}; Sjoerd: {0[Sjoerd]}; '
...       'Dcab: {0[Dcab]}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

Это также можно сделать, передав таблицу в качестве аргументов ключевого слова с обозначением «**».

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {Jack}; Sjoerd: {Sjoerd}; Dcab: {Dcab}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

Это особенно полезно в сочетании со встроенной функцией vars(), которая возвращает словарь, содержащий все локальные переменные.

В качестве примера, следующие строки производят аккуратно выровненный набор столбцов, дающих целые числа и их квадраты и кубы:

>>> for x in range(1, 11):
...     print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

2d, 3d и 4d после : обосзначают отступ а 2, 3 и 4 символа от строки слева. То есть {1:3d} отступает 3 символа от {0:2d}. Но мы видим 4 символа, почему? Потому что print() метод добавляет оступ между своими аргументами. и поэтому между {1:3d} и {0:2d} стоит на 1 оступ больше.

Ручное форматирование строк

Вот та же таблица квадратов и кубов, отформатированная вручную:

>>>

>>> for x in range(1, 11):
...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
...     # Не забудьте поставить end=' ' в конце функции
...     print(repr(x*x*x).rjust(4))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

Методы str.rjust(), str.ljust() и str.center() работают по принципу {str:2}. Они создают отсут от аргумента слева.

Есть еще один метод, str.zfill(), который дополняет цифровую строку слева нулями. Он понимает знаки плюс и минус

>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'

Старое форматирование строк

С помощью оператора %(модуль) можно также форматировать строки. Эта операция называется интерполяцией. Например:

>>> import math
>>> print('The value of pi is approximately %.3f.' % math.pi)
The value of pi is approximately 3.142.

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

Чтение и запись файлов

Чтобы открыть или создать файл нам понадобится функция open(filename, mode):

Советуем вводить расширение файлы, т. к. если вы захотите создать например не txt, а python файл, могут возникнуть трудности.

>>> f = open('workfile.txt', 'w')

Первая строка - это имя файла, а вторая - это режим открытия, есть несколько режимов открытия файла:

  • "r" только чтение
  • "w" только запись. Прочитать файл у вас не получится. И если такого файла не существует, он будет создан. И если в файле есть какие-либо данные он их удалит
  • "a" добавляет в файл некоторые данные
  • "r+" открывает файл для чтения и записи
  • "b" открывает файл в двоичном режиме. Используйте это к тому, что не является текстовым файлом

Если этот аргумент опущен, то по умолчанию будет стоять "r".

Файлы лучше открывать с использованием контрукции with. Он более удобен и даже, если возникнут ошибки или исключения он закроется без ошибок:

>>> with open('workfile') as f:
...     read_data = f.read()

>>> # We can check that the file has been automatically closed.
>>> f.closed
True

После того, как вы проделали все действия над файло обязательно закройте его с помощью метода f.close(). Это освободит используемые системные ресурсы.

Если вы явно не закроете файл, сборщик мусора в Python в конечном итоге уничтожит объект и закроет открытый файл для вас, но файл может оставаться открытым некоторое время. Другой риск состоит в том, что разные реализации Python будут выполнять эту очистку в разное время.

Псоел закрытия файла вы уже не сможете к нему обращаться:

>>> f.close()
>>> f.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.

Методы файловых объектов

Чтобы прочитать содержимое файла, вызовите f.read(size)метод, который читает некоторое количество данных и возвращает его в виде строки (в текстовом режиме) или байтового объекта (в двоичном режиме). размер является необязательным числовым аргументом. Если размер опущен или отрицателен, все содержимое файла будет прочитано и возвращено. Если достигнут конец файла, f.read()вернется пустая строка ( '').

>>> f.read()
'This is the entire file.\n'
>>> f.read()
''

f.readline() читает одну строку из файла; символ новой строки ( \n) остается в конце строки и пропускается только в последней строке файла, если файл не заканчивается новой строкой. Это делает возвращаемое значение однозначным:

>>> f.readline()
'This is the first line of the file.\n'
>>> f.readline()
'Second line of the file\n'
>>> f.readline()
''

Для чтения строк из файла вы можете зациклить объект файла:

>>> for line in f:
...     print(line, end='')
...
This is the first line of the file.
Second line of the file

Если вы хотите прочитать все строки файла в списке, вы также можете использовать list(f)или f.readlines().

Другие типы объектов необходимо преобразовать - либо в строку (в текстовом режиме), либо в байтовый объект (в двоичном режиме) - перед их записью:

>>> value = ('the answer', 42)
>>> s = str(value)  # преобразуем кортеж в строку
>>> f.write(s)
18

Чтобы изменить положение объекта файла, используйте f.seek(offset, whence). Положение вычисляется на основе добавления смещения к контрольной точке; контрольная точка выбирается аргументом whence. Откуда значение 0 измеряет от начала файла, 1 использует текущую позицию файла, а 2 использует конец файла в качестве контрольной точки. По умолчанию whence равно нулю:

>>> f = open('workfile', 'rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5)      # Идем на 5-ую позициюв файле
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2)  # Идем на 3 позицию с конца
13
>>> f.read(1)
b'd'

Сохранение структурированных данных с помощью json

Вместо того, чтобы пользователи постоянно писали и отлаживали код для сохранения сложных типов данных в файлах, Python позволяет вам использовать популярный формат обмена данными, называемый JSON (JavaScript Object Notation) . Вызываемый стандартный модуль json может принимать иерархии данных Python и преобразовывать их в строковые представления; этот процесс называется сериализацией . Восстановление данных из строкового представления называется десериализацией .

Если у вас есть объект x, вы можете просмотреть его строковое представление JSON с помощью простой строки кода:

>>> import json
>>> json.dumps([1, 'simple', 'list'])
'[1, "simple", "list"]'

Другой вариант dumps()вызываемой функции dump()просто сериализует объект в текстовый файл . Итак, если f объект текстового файла открыт для записи, мы можем сделать это:

json.dump(x, f)

Чтобы снова декодировать объект, если f это объект текстового файла, который был открыт для чтения:

x = json.load(f)

Заключение

А теперь идите и тварите красоту строками

Пост был создан для тг-канала @coolcoders