ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 05.12.2023
Просмотров: 834
Скачиваний: 3
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
Глава 6. Строки и двоичные данные
83
bytes
— неизменяемая последовательность байтов. Каждый элемент последовательно- сти может хранить целое число от
0
до
255
, которое обозначает код символа. Объект типа bytes поддерживает большинство строковых методов и, если это возможно, выво- дится как последовательность символов. Однако доступ по индексу возвращает целое число, а не символ:
>>> s = bytes("стр str", "cp1251")
>>> s[0], s[5], s[0:3], s[4:7]
(241, 116, b'\xf1\xf2\xf0', b'str')
>>> s b'\xf1\xf2\xf0 str'
Объект типа bytes может содержать как однобайтовые, так и многобайтовые символы.
Обратите внимание на то, что функции и методы строк некорректно работают с много- байтовыми кодировками, — например, функция len()
вернет количество байтов, а не символов:
>>> len("строка")
6
>>> len(bytes("строка", "cp1251"))
6
>>> len(bytes("строка", "utf-8"))
12
bytearray
— изменяемая последовательность байтов. Тип bytearray аналогичен типу bytes
, но позволяет изменять элементы по индексу и содержит дополнительные методы, дающие возможность добавлять и удалять элементы:
>>> s = bytearray("str", "cp1251")
>>> s[0] = 49; s # Можно изменить символ bytearray(b'1tr')
>>> s.append(55); s # Можно добавить символ bytearray(b'1tr7')
Во всех случаях, когда речь идет о текстовых данных, следует использовать тип str
. Имен- но этот тип мы будем называть словом «строка». Типы bytes и bytearray следует задейст- вовать для записи двоичных данных (например, изображений) и промежуточного хранения строк. Более подробно типы bytes и bytearray мы рассмотрим в конце этой главы.
6.1. Создание строки
Создать строку можно следующими способами:
с помощью функции str([<Объект>[, <Кодировка>[, <Обработка ошибок>]]])
. Если указан только первый параметр, функция возвращает строковое представление любого объекта. Если параметры не указаны вообще, возвращается пустая строка:
>>> str(), str([1, 2]), str((3, 4)), str({"x": 1})
('', '[1, 2]', '(3, 4)', "{'x': 1}")
>>> str(b"\xf1\xf2\xf0\xee\xea\xe0")
"b'\\xf1\\xf2\\xf0\\xee\\xea\\xe0'"
Обратите внимание на преобразование объекта типа bytes
. Мы получили строковое представление объекта, а не нормальную строку. Чтобы получить из объектов типа bytes и bytearray именно строку, следует указать кодировку во втором параметре:
84
Часть I. Основы языка Python
>>> str(b"\xf1\xf2\xf0\xee\xea\xe0", "cp1251")
'строка'
В третьем параметре могут быть указаны значения "strict"
(при ошибке возбуждается исключение
UnicodeDecodeError
— значение по умолчанию),
"replace"
(неизвестный символ заменяется символом, имеющим код
\uFFFD
) или "ignore"
(неизвестные символы игнорируются):
>>> obj1 = bytes("строка1", "utf-8")
>>> obj2 = bytearray("строка2", "utf-8")
>>> str(obj1, "utf-8"), str(obj2, "utf-8")
('строка1', 'строка2')
>>> str(obj1, "ascii", "strict")
Traceback (most recent call last):
File "
", line 1, in
UnicodeDecodeError: 'ascii' codec can't decode byte
0xd1 in position 0: ordinal not in range(128)
>>> str(obj1, "ascii", "ignore")
'1'
указав строку между апострофами или двойными кавычками:
>>> 'строка', "строка", '"x": 5', "'x': 5"
('строка', 'строка', '"x": 5', "'x': 5")
>>> print('Строка1\nСтрока2')
Строка1
Строка2
>>> print("Строка1\nСтрока2")
Строка1
Строка2
В некоторых языках программирования (например, в PHP) строка в апострофах отлича- ется от строки в кавычках тем, что внутри апострофов специальные символы выводятся как есть, а внутри кавычек они интерпретируются. В языке Python никакого отличия между строкой в апострофах и строкой в кавычках нет. Если строка содержит кавычки, то ее лучше заключить в апострофы, и наоборот. Все специальные символы в таких строках интерпретируются — например, последовательность символов
\n преобразуется в символ новой строки. Чтобы специальный символ выводился как есть, его необходимо экранировать с помощью слэша:
>>> print("Строка1\\nСтрока2")
Строка1\nСтрока2
>>> print('Строка1\\nСтрока2')
Строка1\nСтрока2
Кавычку внутри строки в кавычках и апостроф внутри строки в апострофах также необ- ходимо экранировать с помощью защитного слэша:
>>> "\"x\": 5", '\'x\': 5'
('"x": 5', "'x': 5")
Следует также заметить, что заключить объект в одинарные кавычки (или апострофы) на нескольких строках нельзя. Переход на новую строку вызовет синтаксическую ошибку:
>>> "string
SyntaxError: EOL while scanning string literal
Глава 6. Строки и двоичные данные
85
Чтобы расположить объект на нескольких строках, следует перед символом перевода строки указать символ
\
, поместить две строки внутри скобок или использовать конка- тенацию внутри скобок:
>>> "string1\ string2" # После \ не должно быть никаких символов 'string1string2'
>>> ("string1"
"string2") # Неявная конкатенация строк 'string1string2'
>>> ("string1" +
"string2") # Явная конкатенация строк 'string1string2'
Кроме того, если в конце строки расположен символ
\
, то его необходимо экранировать, иначе будет выведено сообщение об ошибке:
>>> print("string\")
SyntaxError: EOL while scanning string literal
>>> print("string\\") string\
указав строку между утроенными апострофами или утроенными кавычками. Такие объ- екты можно разместить на нескольких строках. Допускается также одновременно ис- пользовать и кавычки, и апострофы без необходимости их экранировать. В остальном такие объекты эквивалентны строкам в апострофах и кавычках. Все специальные симво- лы в таких строках интерпретируются:
>>> print('''Строка1
Строка2''')
Строка1
Строка2
>>> print("""Строка1
Строка2""")
Строка1
Строка2
Если строка не присваивается переменной, то она считается строкой документирования.
Такая строка сохраняется в атрибуте
__doc__
того объекта, в котором расположена. В каче- стве примера создадим функцию со строкой документирования, а затем выведем содержи- мое строки:
>>> def test():
"""Это описание функции""" pass
>>> print(test.__doc__)
Это описание функции
Поскольку выражения внутри таких строк не выполняются, то утроенные кавычки (или утроенные апострофы) очень часто используются для комментирования больших фрагмен- тов кода на этапе отладки программы.
86
Часть I. Основы языка Python
Если перед строкой разместить модификатор r
, то специальные символы внутри строки выводятся как есть. Например, символ
\n не будет преобразован в символ перевода строки.
Иными словами, он будет считаться последовательностью символов
\
и n
:
>>> print("Строка1\nСтрока2")
Строка1
Строка2
>>> print(r"Строка1\nСтрока2")
Строка1\nСтрока2
>>> print(r"""Строка1\nСтрока2""")
Строка1\nСтрока2
Такие неформатированные строки удобно использовать в шаблонах регулярных выраже- ний, а также при указании пути к файлу или каталогу:
>>> print(r"C:\Python36\lib\site-packages")
C:\Python36\lib\site-packages
Если модификатор не указать, то все слэши при указании пути необходимо экранировать:
>>> print("C:\\Python36\\lib\\site-packages")
C:\Python36\lib\site-packages
Если в конце неформатированной строки расположен слэш, то его необходимо экраниро- вать. Однако следует учитывать, что этот слэш будет добавлен в исходную строку:
>>> print(r"C:\Python36\lib\site-packages\")
SyntaxError: EOL while scanning string literal
>>> print(r"C:\Python36\lib\site-packages\\")
C:\Python36\lib\site-packages\\
Чтобы избавиться от лишнего слэша, можно использовать операцию конкатенации строк, обычные строки или удалить слэш явным образом:
>>> print(r"C:\Python36\lib\site-packages" + "\\") # Конкатенация
C:\Python36\lib\site-packages\
>>> print("C:\\Python36\\lib\\site-packages\\") # Обычная строка
C:\Python36\lib\site-packages\
>>> print(r"C:\Python36\lib\site-packages\\"[:-1]) # Удаление слэша
C:\Python36\lib\site-packages\
6.2. Специальные символы
Специальные символы — это комбинации знаков, обозначающих служебные или непеча- таемые символы, которые невозможно вставить обычным способом. Приведем перечень спе- циальных символов, допустимых внутри строки, перед которой нет модификатора r
:
\n
— перевод строки;
\r
— возврат каретки;
\t
— знак табуляции;
\v
— вертикальная табуляция;
\a
— звонок;
Глава 6. Строки и двоичные данные
87
\b
— забой;
\f
— перевод формата;
\0
— нулевой символ (не является концом строки);
\"
— кавычка;
\'
— апостроф;
\N
— символ с восьмеричным кодом
N
. Например,
\74
соответствует символу
<
;
\xN
— символ с шестнадцатеричным кодом
N
. Например,
\x6a соответствует символу j
;
\\
— обратный слэш;
\uxxxx
— 16-битный символ Unicode. Например,
\u043a соответствует русской букве к
;
\Uxxxxxxxx
— 32-битный символ Unicode.
Если после слэша не стоит символ, который вместе со слэшем интерпретируется как спец- символ, то слэш сохраняется в составе строки:
>>> print("Этот символ \не специальный")
Этот символ \не специальный
Тем не менее, лучше экранировать слэш явным образом:
>>> print("Этот символ \\не специальный")
Этот символ \не специальный
6.3. Операции над строками
Как вы уже знаете, строки относятся к последовательностям. Как и все последовательности, строки поддерживают обращение к элементу по индексу, получение среза, конкатенацию, повторение и проверку на вхождение. Рассмотрим эти операции подробно.
К любому символу строки можно обратиться как к элементу списка — достаточно указать его индекс в квадратных скобках. Нумерация начинается с нуля:
>>> s = "Python"
>>> s[0], s[1], s[2], s[3], s[4], s[5]
('P', 'y', 't', 'h', 'o', 'n')
Если символ, соответствующий указанному индексу, отсутствует в строке, возбуждается исключение
IndexError
:
>>> s = "Python"
>>> s[10]
Traceback (most recent call last):
File "
", line 1, in
IndexError: string index out of range
В качестве индекса можно указать отрицательное значение. В этом случае смещение будет отсчитываться от конца строки, а точнее — чтобы получить положительный индекс, значе- ние вычитается из длины строки:
>>> s = "Python"
>>> s[-1], s[len(s)-1]
('n', 'n')
88
Часть I. Основы языка Python
Так как строки относятся к неизменяемым типам данных, то изменить символ по индексу нельзя:
>>> s = "Python"
>>> s[0] = "J" # Изменить строку нельзя
Traceback (most recent call last):
File "
", line 1, in
TypeError: 'str' object does not support item assignment
Чтобы выполнить изменение, можно воспользоваться операцией извлечения среза, которая возвращает указанный фрагмент строки. Формат операции:
[<Начало>:<Конец>:<Шаг>]
Все параметры здесь не являются обязательными. Если параметр
<Начало>
не указан, то ис- пользуется значение
0
. Если параметр
<Конец>
не указан, то возвращается фрагмент до кон- ца строки. Следует также заметить, что символ с индексом, указанным в этом параметре, не входит в возвращаемый фрагмент. Если параметр
<Шаг>
не указан, то используется значе- ние
1
. В качестве значения параметров можно указать отрицательные значения.
Рассмотрим несколько примеров:
сначала получим копию строки:
>>> s = "Python"
>>> s[:] # Возвращается фрагмент от позиции 0 до конца строки 'Python'
теперь выведем символы в обратном порядке:
>>> s[::-1] # Указываем отрицательное значение в параметре <Шаг>
'nohtyP'
заменим первый символ в строке:
>>> "J" + s[1:] # Извлекаем фрагмент от символа 1 до конца строки 'Jython'
удалим последний символ:
>>> s[:-1] # Возвращается фрагмент от 0 до len(s)-1
'Pytho'
получим первый символ в строке:
>>> s[0:1] # Символ с индексом 1 не входит в диапазон 'P'
а теперь получим последний символ:
>>> s[-1:] # Получаем фрагмент от len(s)-1 до конца строки 'n'
и, наконец, выведем символы с индексами 2, 3 и 4:
>>> s[2:5] # Возвращаются символы с индексами 2, 3 и 4
'tho'
Узнать количество символов в строке (ее длину) позволяет функция len()
:
>>> len("Python"), len("\r\n\t"), len(r"\r\n\t")
(6, 3, 6)
Глава 6. Строки и двоичные данные
89
Теперь, когда мы знаем количество символов, можно перебрать все символы с помощью цикла for
:
>>> s = "Python"
>>> for i in range(len(s)): print(s[i], end=" ")
Результат выполнения:
P y t h o n
Так как строки поддерживают итерации, мы можем просто указать строку в качестве пара- метра цикла:
>>> s = "Python"
>>> for i in s: print(i, end=" ")
Результат выполнения будет таким же:
P y t h o n
Соединить две строки в одну строку (выполнить их конкатенацию) позволяет оператор
+
:
>>> print("Строка1" + "Строка2")
Строка1Строка2
Кроме того, можно выполнить неявную конкатенацию строк. В этом случае две строки ука- зываются рядом без оператора между ними:
>>> print("Строка1" "Строка2")
Строка1Строка2
Обратите внимание на то, что если между строками указать запятую, то мы получим кор- теж, а не строку:
>>> s = "Строка1", "Строка2"
>>> type(s) # Получаем кортеж, а не строку
Если соединяются, например, переменная и строка, то следует обязательно указывать сим- вол конкатенации строк, иначе будет выведено сообщение об ошибке:
>>> s = "Строка1"
>>> print(s + "Строка2") # Нормально
Строка1Строка2
>>> print(s "Строка2") # Ошибка
SyntaxError: invalid syntax
При необходимости соединить строку со значением другого типа (например, с числом) сле- дует произвести явное преобразование типов с помощью функции str()
:
>>> "string" + str(10)
'string10'
Кроме рассмотренных операций, строки поддерживают операцию повторения, проверки на вхождение и невхождение. Повторить строку указанное количество раз можно с помощью оператора
*
, выполнить проверку на вхождение фрагмента в строку позволяет оператор in
, а проверить на невхождение — оператор not in
:
>>> "-" * 20
'--------------------'
>>> "yt" in "Python" # Найдено
True
90
Часть I. Основы языка Python
>>> "yt" in "Perl" # Не найдено
False
>>> "PHP" not in "Python" # Не найдено
True
6.4. Форматирование строк
Вместо соединения строк с помощью оператора
+
лучше использовать форматирование. Эта операция позволяет соединять строки со значениями любых других типов и выполняется быстрее конкатенации.
П
РИМЕЧАНИЕ
В последующих версиях Python оператор форматирования % может быть удален. Вместо этого оператора в новом коде следует использовать метод format(), который рассматри- вается в следующем разделе.
Операция форматирования записывается следующим образом:
<Строка специального формата> % <Значения>
Внутри параметра
<Строка специального формата>
могут быть указаны спецификаторы, имеющие следующий синтаксис:
%[(<Ключ>)][<Флаг>][<Ширина>][.<Точность>]<Тип преобразования>
Количество спецификаторов внутри строки должно быть равно количеству элементов в па- раметре
<Значения>
. Если используется только один спецификатор, то параметр
<Значения>
может содержать одно значение, в противном случае необходимо указать значения через запятую внутри круглых скобок, создавая тем самым кортеж:
>>> "%s" % 10 # Один элемент '10'
>>> "%s — %s — %s" % (10, 20, 30) # Несколько элементов '10 — 20 — 30'
Параметры внутри спецификатора имеют следующий смысл:
<Ключ>
— ключ словаря. Если задан ключ, то в параметре
<Значения>
необходимо ука- зать словарь, а не кортеж:
>>> "%(name)s — %(year)s" % {"year": 1978, "name": "Nik"}
'Nik — 1978'
<Флаг>
— флаг преобразования. Может содержать следующие значения:
•
#
— для восьмеричных значений добавляет в начало комбинацию символов
0o
, для шестнадцатеричных значений — комбинацию символов
0x
(если используется тип x
) или
0X
(если используется тип
X
), для вещественных чисел предписывает всегда вы- водить дробную точку, даже если задано значение
0
в параметре
<Точность>
:
>>> print("%#o %#o %#o" % (0o77, 10, 10.5))
0o77 0o12 0o12
>>> print("%#x %#x %#x" % (0xff, 10, 10.5))
0xff 0xa 0xa
>>> print("%#X %#X %#X" % (0xff, 10, 10.5))
0XFF 0XA 0XA
Глава 6. Строки и двоичные данные
91
>>> print("%#.0F %.0F" % (300, 300))
300. 300
•
0
— задает наличие ведущих нулей для числового значения:
>>> "'%d' — '%05d'" % (3, 3) # 5 — ширина поля "'3' — '00003'"
•
-
— задает выравнивание по левой границе области. По умолчанию используется выравнивание по правой границе. Если флаг указан одновременно с флагом
0
, то действие флага
0
будет отменено:
>>> "'%5d' - '%-5d'" % (3, 3) # 5 — ширина поля "' 3' - '3 '"
>>> "'%05d' - '%-05d'" % (3, 3)
"'00003' - '3 '"
• пробел
— вставляет пробел перед положительным числом. Перед отрицательным числом будет стоять минус:
>>> "'% d' - '% d'" % (-3, 3)
"'-3' - ' 3'"
•
+
— задает обязательный вывод знака как для отрицательных, так и для положитель- ных чисел. Если флаг
+
указан одновременно с флагом пробел
, то действие флага про- бел будет отменено:
>>> "'%+d' - '%+d'" % (-3, 3)
"'-3' - '+3'"
<Ширина>
— минимальная ширина поля. Если строка не помещается в указанную шири- ну, значение игнорируется, и строка выводится полностью:
>>> "'%10d' - '%-10d'" % (3, 3)
"' 3' - '3 '"
>>> "'%3s''%10s'" % ("string", "string")
"'string'' string'"
Вместо значения можно указать символ «
*
». В этом случае значение следует задать внутри кортежа:
>>> "'%*s''%10s'" % (10, "string", "str")
"' string'' str'"
<Точность>
— количество знаков после точки для вещественных чисел. Перед этим параметром обязательно должна стоять точка:
>>> import math
>>> "%s %f %.2f" % (math.pi, math.pi, math.pi)
'3.141592653589793 3.141593 3.14'
Вместо значения можно указать символ «
*
». В этом случае значение следует задать внутри кортежа:
>>> "'%*.*f'" % (8, 5, math.pi)
"' 3.14159'"
<Тип преобразования>
— задает тип преобразования. Параметр является обязательным.
92
Часть I. Основы языка Python
В параметре
<Тип преобразования>
могут быть указаны следующие символы:
• s
— преобразует любой объект в строку с помощью функции str()
:
>>> print("%s" % ("Обычная строка"))
Обычная строка
>>> print("%s %s %s" % (10, 10.52, [1, 2, 3]))
10 10.52 [1, 2, 3]
• r
— преобразует любой объект в строку с помощью функции repr()
:
>>> print("%r" % ("Обычная строка"))
'Обычная строка'
• a
— преобразует объект в строку с помощью функции ascii()
:
>>> print("%a" % ("строка"))
'\u0441\u0442\u0440\u043e\u043a\u0430'
• c
— выводит одиночный символ или преобразует числовое значение в символ. В ка- честве примера выведем числовое значение и соответствующий этому значению символ:
>>> for i in range(33, 127): print("%s => %c" % (i, i))
• d
и i
— возвращают целую часть числа:
>>> print("%d %d %d" % (10, 25.6, -80))
10 25 -80
>>> print("%i %i %i" % (10, 25.6, -80))
10 25 -80
• o
— восьмеричное значение:
>>> print("%o %o %o" % (0o77, 10, 10.5))
77 12 12
>>> print("%#o %#o %#o" % (0o77, 10, 10.5))
0o77 0o12 0o12
• x
— шестнадцатеричное значение в нижнем регистре:
>>> print("%x %x %x" % (0xff, 10, 10.5)) ff a a
>>> print("%#x %#x %#x" % (0xff, 10, 10.5))
0xff 0xa 0xa
•
X
— шестнадцатеричное значение в верхнем регистре:
>>> print("%X %X %X" % (0xff, 10, 10.5))
FF A A
>>> print("%#X %#X %#X" % (0xff, 10, 10.5))
0XFF 0XA 0XA
• f
и
F
— вещественное число в десятичном представлении:
>>> print("%f %f %f" % (300, 18.65781452, -12.5))
300.000000 18.657815 -12.500000
>>> print("%F %F %F" % (300, 18.65781452, -12.5))
300.000000 18.657815 -12.500000
>>> print("%#.0F %.0F" % (300, 300))
300. 300