понедельник, 7 декабря 2015 г.

Комментарии в Python; Форматирование строк: Операторы форматирования и метод format()

Комментарии



На этой стадии, мы владеем уже достаточно обширным набором инструментария и можем писать достаточно "запутанный" код. После написания кода в несколько десятков строк, уже через несколько дней, его будет достаточно сложно прочесть. Другим же людям, будет его прочесть еще сложнее.
А если представить, что в крупных проектах мегабайты текстовых файлов с кодом, то они становятся еще более сложно читаемыми. Эту ситуацию спасают комментарии внутри кода. Эти комментарии, программисты оставляют для того, чтобы со временем, они могли прояснить тот или иной фрагмент кода и описать, какие-то действия, происходящие в определенных частях программного кода. Для ваших коллег и для вас же - это значительно облегчит читаемость кода.

В питоне различают два типа комментариев: Однострочный и многострочный. Однострочный комментарий начинается с символа "#", может быть как в отдельной строке, так и оканчивать строку с кодом, но обязательно должен быть однострочным, Т.Е. Не должен разбиваться на две строки. Он может оканчивать строку с кодом, но не может находиться в середине строки между двух частей кода. Кпримеру:

i = 0 # Счетчик для цикла

while i < 5:

    # Цикл будет выполняться исходя из условия выше

    i += 1

    ...


Многострочные комментарии заключаются в тройные кавычки""". Они могут разбиваться на несколько строк и быть достаточно длинными. По-факту, хоть сочинение пишите. Многострочный комментарий должен начинаться с новой строки и может продолжаться в других строках. Кпримеру:

for i in l:

    """Обходим список для нахождения необходимого элемента

После нахождения, обрываем цикл и сохраняем результат в переменную x

Если необходимый элемент найден небудет, сообщаем про это пользователю"""

    if ...:

        ...

    ...


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

Начинающие программисты, да и не только начинающие, часто пишут в комментариях очевидные вещи, что-то вроде "Я объявил тут переменную x". Пытайтесь избегать комментариев, которые дублируют произведенное действие человеческим языком. Перед написанием комментария, попробуйте задавать себе такие вопросы: "Для чего служит этот фрагмент?", "Какую цель я приследую этим фрагментом кода?", "Что я делаю при помощи этого фрагмента кода?", "Что в этом фрагменте неочевидно?"... Подобный ряд вопросов, поможет сконструировать правильный комментарий, который действительно поможет сопровождать код в будущем и сделает его более читаемым.


Операторы форматирования строки



Сейчас под выражением "форматирование строки", мы имеем ввиду разворачивание значений переменных в строке, Т.Е. КОгда есть необходимость в какой-тро строке, вставить значения каких-то переменных. Ранее мы делали это при помощи "+" - соединения строк и "," запись численных выражений после строк. Выглядело это, как минимум, некрасиво.

>>> a = "Hello"

>>> b = "dear"

>>> a + ' ' + b

'Hello dear'

>>>


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

Давайте рассмотрим следующий вариант:

>>> a = "Vasya"

>>> print "Привет %s" % a

Привет Vasya

>>>


Что происходит? Все достаточно просто. Оператор %s в нашей строке, заменяется на переменную, которая стоит справа от знака % после нашей строки.

Давайте рассмотрим еще один пример:

>>> name = "Vasya"

>>> lastname = "Pupkin"

>>> age = 25

>>> print "Имя %s, фамилия %s, возраст %d" % (name,lastname,age)

Имя Vasya, фамилия Pupkin, возраст 25

>>>


Во-первых обратите внимание, что если переменных более одной, мы передаем их в кортеже (). Также вы могли заметить, что строчные значения переменных, я передал при помощи оператора %s, а переменную ссылающуюся на число, при помощи оператора %d. Это работает только так. Каждый оператор может развернуть значение определенного типа: %s - строку, %d - число и Т.Д. Более подробный список операторов, будет приведен ниже.

Первый вопрос, который напрашивается сам собой: "Как нам вывести значение одной переменной несколько раз в одной строке?". Ответ очевиден, нам прийдется передать эту переменную в кортеже столько раз и в том порядке, в котором мы разворачиваем значения этих переменных в нашей строке. Это топорно и неудобно. Мы всегда должны записывать переменные в строгом порядке, который будет соответствовать разворачиванию их операторами в строке, да еще и повторять их при необходимости.


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

'%d', '%i', '%u'

Десятичное число.

'%o'

Число в восьмеричной системе счисления.

'%x'

Число в шестнадцатеричной системе счисления (буквы в нижнем регистре).

'%X'

Число в шестнадцатеричной системе счисления (буквы в верхнем регистре).

'%e'

Число с плавающей точкой с экспонентой (экспонента в нижнем регистре).

'%E'

Число с плавающей точкой с экспонентой (экспонента в верхнем регистре).

'%f', '%F'

Число с плавающей точкой (обычный формат).

'%g'

Число с плавающей точкой. с экспонентой (экспонента в нижнем регистре), если она меньше, чем -4 или точности, иначе обычный формат.

'%G'

Число с плавающей точкой. с экспонентой (экспонента в верхнем регистре), если она меньше, чем -4 или точности, иначе обычный формат.

'%c'

Символ (строка из одного символа или число - код символа).

'%r'

Строка (литерал python).

'%s'

Строка (как обычно воспринимается пользователем).

'%%'

Знак '%'.


Операторы форматирования (дополнительно)



Тут я коротко продемонстрирую дополнительные возможности операторов форматирования.

Спецификаторы преобразования записываются в следующем порядке:

1. %.

2. Ключ (опционально), определяет, какой аргумент из значения будет подставляться.

3. Флаги преобразования.

4. Минимальная ширина поля. Если *, значение берётся из кортежа.

5. Точность, начинается с '.', затем - желаемая точность.

6. Модификатор длины (опционально).

7. Тип (см. таблицу выше).

>>>

>>> print ('%(language)s has %(number)03d quote types.' % {"language": "Python", "number": 2})

Python has 002 quote types.

Флаги преобразования:

"#"

Значение будет использовать альтернативную форму.

"0"

Свободное место будет заполнено нулями.

"-"

Свободное место будет заполнено пробелами справа.

" "

Свободное место будет заполнено пробелами справа.

"+"

Свободное место будет заполнено пробелами слева.

>>>

>>> '%.2s' % 'Hello!'

'He'

>>> '%.*s' % (2, 'Hello!')

'He'

>>> '%-10d' % 25

'25        '

>>> '%+10f' % 25

'+25.000000'

>>> '%+10s' % 'Hello'

'     Hello'

Более подробно разбирать эти возможности не имеет смысла, ввиду их редкого использования.


Метод форматирования строк format()



На смену операторам форматирования, кнам пришел строчный метод format(). Этот метод куда более гибкий, удобный и многогранный в использовании. Давайте рассмотрим его применение для разворачивания значений переменных в строке.

>>> name = "Vasya"

>>> lastname = "Pupkin"

>>> age = 25

>>> print "{} {}, возраст {}".format(name,lastname,age)

Vasya Pupkin, возраст 25

>>>


Тут все достаточно очевидно. Фигурные скобочки {}, определяют места развертывания переменных в строке, а методу format(), мы передаем переменные, которые нужно разворачивать. На первый взгляд, ничего по сравнению с операторами форматирования не изменилось. Мы попрежнему неможем никак управлять нашим разворачиванием. Разница только в том, что нам уже ненужно запоминать кучку операторов, для разворачивания значений разных типов. Ничего, это только начало. Давайте наращивать функционал последовательно. Давайте рассмотрим следующий вариант:

>>> name = "Vasya"

>>> lastname = "Pupkin"

>>> age = 25

>>> print "{0} {1}, возраст {2}".format(name,lastname,age)

Vasya Pupkin, возраст 25

>>>


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

>>> print "{1} {0}, возраст {2}".format(name,lastname,age)

Pupkin Vasya, возраст 25

>>>


Выводимая строка изменилась, Мы поменяли местами значения. Вы могли заметить, что на не пришлось менять местами переменные, которые мы передали в метод, мы просто поменяли цифры в фигурных скобочках {}. Эти цифры, являются своеобразными индексами тех переменных, которые мы хотим развернуть в нашей строке. В последнем примере, мы развернули переменную под индексом 1, потом 0 и 2, Т.Е. Вторую, первую и третью переданные в метод переменные. Это значит, что мы, указывая индексы переменных, которые были переданы в метод, можем разворачивать их в нужном нам порядке. Также, мы можем несколько раз вывести в строке значение одной переменной, несколько раз  указав ее индекс в фигурных скобочках.

>>> print "{1} {1}, возраст {2}".format(name,lastname,age)

Pupkin Pupkin, возраст 25

>>>


Согласитесь, это уже куда более гибкий и удобный способ форматирования строки, в сравнении с операторами форматирования. Но и на этом гибкость этого метода для разворачивания значений переменных не заканчивается. Давайте рассмотрим вариант, именованных аргументов.

>>> a = "Vasya"

>>> b = "Pupkin"

>>> c = 25

>>> print "{name} {lastname}, возраст {age}".format(age=c,name=a,lastname=b)

Vasya Pupkin, возраст 25

>>>


Тут еще интереснее. Необходимые данные, находились под ничего не говорящими переменными a, b и c. При передаче этих переменных в наш метод, мы дали им осмысленные названия вида (название=переменная), после чего использовали эти названия в наших фигурных скобочках {}.

Методу format, мы можем передавать список значений и разворачивать их внутри нашей строки. Происходит это следующим образом:

>>> l = ["Vasya", "Pupkin", 25]

>>> l

['Vasya', 'Pupkin', 25]

>>> print "{0} {1}, возраст {2}".format(*l)

Vasya Pupkin, возраст 25

>>>


Тут все более чем очевидно. Мы передали список и обращались к его элементам по индексам, но при передаче списка, перед переменной, мы указали знак "*", что явно сообщило методу format() о том, что мы будем разворачивать элементы этого списка. Что произойдет, если мы опустим "*", перед указанием аргумента со списком?

>>> print "{0} {1}, возраст {2}".format(l)

Traceback (most recent call last):

  File "", line 1, in

IndexError: tuple index out of range

>>>


Метод не знал, что мы передали список и пытался искать в себе обычные аргументы под индексами 1 и 2, к которым мы обращались в строке.

Схожим образом, мы можем передать в метод format() и словарь.

>>> db = {"name":"Vasya", "lastname":"Pupkin", "age":25}

>>> db

{'lastname': 'Pupkin', 'age': 25, 'name': 'Vasya'}

>>> print "{name} {lastname}, возраст {age}".format(**db)

Vasya Pupkin, возраст 25

>>>


Это очень похоже на передачу именованных аргументов с той только разницей, что мы передали в наш метод словарь. Если перед передачей списка мы указывали одну звездочку "*", то перед передачей словаря, мы ставим две звездочки "**" перед аргументом в методе format(), а в фигурных скобочках строки, мы обращаемся к ключам переданного словаря, для разворачивания их значений.

Мы рассмотрели все варианты разворачивания переменных в строке, при помощи метода format(). В дальнейшем, я крайне рекомендую использовать этот метод вместо операторов форматирования, Т.К. Этот способ является более новым, гибким и официальные источники, советуют нам придерживаться именно этого метода.



Метод format() (дополнительно)



Далее я приведу дополнительные возможности строчного метода format(). Более обширную информацию про данный метод, вы можете посмотреть в статье на хабре, или в официальной документации по Python.


Внимание! Дальнейшее является фрагментом статьи про метод format()

Снова начнем с простого: если нужно вывести строку заданной длины, то после имени переменной добавляем двоеточие (:) и затем количество символов. Так, чтобы вывести мое имя и дополнить его до десяти символов пробелами я должен делать так:


>>> "Your name is {name:10}".format(name="Reuven")


'Your name is Reuven    '


(Обратите внимание что строка дополнена пробелами после имени.)


Если нужно задать выравнивание по правой стороне блока — используется знак > между: и числом:


>>> "Your name is {name:>10}".format(name="Reuven")


'Your name is     Reuven'


И да, можно явно указать что я хочу выравнивания по левой стороне с помощью знака <

Если нужно вывести значение в центре блока, то вместо < и > используется символ ^:


>>> "Your name is {name:*^10}".format(name="Reuven")


'Your name is **Reuven**'


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


>>> "The price is ${number}.".format(number=123)


'The price is $123.'


Комментариев нет:

Отправить комментарий