Главная страница

ээдд. Прохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен. Николай Прохоренок Владимир Дронов


Скачать 7.92 Mb.
НазваниеНиколай Прохоренок Владимир Дронов
Дата05.05.2023
Размер7.92 Mb.
Формат файлаpdf
Имя файлаПрохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен.pdf
ТипДокументы
#1111379
страница10 из 83
1   ...   6   7   8   9   10   11   12   13   ...   83
-2.7755575615628914e-17
Ожидаемым был бы результат
0.0
, но, как видно из примера, мы получили совсем другое значение. Если необходимо производить операции с фиксированной точностью, то следует использовать модуль decimal
:
>>> from decimal import Decimal
>>> Decimal("0.3") - Decimal("0.1") - Decimal("0.1") - Decimal("0.1")
Decimal('0.0')
Кроме того, можно использовать дроби, поддержка которых реализована в модуле fractions
. При создании дроби можно указать как два числа: числитель и знаменатель, так и одно число или строку, содержащую число, которое будет преобразовано в дробь.
Для примера создадим несколько дробей. Вот так формируется дробь
4
/
5
:
>>> from fractions import Fraction
>>> Fraction(4, 5)
Fraction(4, 5)
А вот так — дробь
1
/
2
, причем можно сделать это тремя способами:
>>> Fraction(1, 2)
Fraction(1, 2)
>>> Fraction("0.5")
Fraction(1, 2)
>>> Fraction(0.5)
Fraction(1, 2)
Над дробями можно производить арифметические операции, как и над обычными числами:
>>> Fraction(9, 5) - Fraction(2, 3)
Fraction(17, 15)
>>> Fraction("0.3") - Fraction("0.1") - Fraction("0.1") - Fraction("0.1")
Fraction(0, 1)
>>> float(Fraction(0, 1))
0.0
Комплексные числа записываются в формате:
<Вещественная часть>+<Мнимая часть>J
Здесь буква
J
может стоять в любом регистре. Примеры комплексных чисел:
>>> 2+5J, 8j
((2+5j), 8j)
Подробное рассмотрение модулей decimal и fractions
, а также комплексных чисел выхо- дит за рамки нашей книги. За подробной информацией обращайтесь к документации по языку Python.

Глава 5. Числа
75
В Python 3.6 появилась возможность для улучшения читаемости кода вставлять в число, записанное в десятичной, двоичной, восьмеричной и шестнадцатеричной системах счисле- ния, символы подчеркивания:
>>> 1_000_000 1000000
>>> 0b1111_1111 255
>>> 0o2_777 1535
>>> 0xab_cd
43981 5.1. Встроенные функции и методы для работы с числами
Для работы с числами предназначены следующие встроенные функции:
 int([<Объект>[, <Система счисления>]])
— преобразует объект в целое число. Во вто- ром параметре можно указать систему счисления преобразуемого числа (значение по умолчанию
10
):
>>> int(7.5), int("71", 10), int("0o71", 8), int("0xA", 16)
(7, 71, 57, 10)
>>> int(), int("0b11111111", 2)
(0, 255)
 float([<Число или строка>])
— преобразует целое число или строку в вещественное число:
>>> float(7), float("7.1"), float("12.")
(7.0, 7.1, 12.0)
>>> float("inf"), float("-Infinity"), float("nan")
(inf, -inf, nan)
>>> float()
0.0
 bin(<Число>)
— преобразует десятичное число в двоичное. Возвращает строковое пред- ставление числа:
>>> bin(255), bin(1), bin(-45)
('0b11111111', '0b1', '-0b101101')
 oct(<Число>)
— преобразует десятичное число в восьмеричное. Возвращает строковое представление числа:
>>> oct(7), oct(8), oct(64)
('0o7', '0o10', '0o100')
 hex(<Число>)
— преобразует десятичное число в шестнадцатеричное. Возвращает стро- ковое представление числа:
>>> hex(10), hex(16), hex(255)
('0xa', '0x10', '0xff')

76
Часть I. Основы языка Python
 round(<Число>[, <Количество знаков после точки>])
— для чисел с дробной частью, меньшей
0.5
, возвращает число, округленное до ближайшего меньшего целого, а для чисел с дробной частью, большей
0.5
, возвращает число, округленное до ближайшего большего целого. Если дробная часть равна
0.5
, то округление производится до бли- жайшего четного числа:
>>> round(0.49), round(0.50), round(0.51)
(0, 0, 1)
>>> round(1.49), round(1.50), round(1.51)
(1, 2, 2)
>>> round(2.49), round(2.50), round(2.51)
(2, 2, 3)
>>> round(3.49), round(3.50), round(3.51)
(3, 4, 4)
Во втором параметре можно указать желаемое количество знаков после запятой. Если оно не указано, используется значение
0
(т. е. число будет округлено до целого):
>>> round(1.524, 2), round(1.525, 2), round(1.5555, 3)
(1.52, 1.52, 1.556)
 abs(<Число>)
— возвращает абсолютное значение:
>>> abs(-10), abs(10), abs(-12.5)
(10, 10, 12.5)
 pow(<Число>, <Степень>[, <Делитель>])
— возводит
<Число>
в
<Степень>
:
>>> pow(10, 2), 10 ** 2, pow(3, 3), 3 ** 3
(100, 100, 27, 27)
Если указан третий параметр, возвращается остаток от деления полученного результата на значение этого параметра:
>>> pow(10, 2, 2), (10 ** 2) % 2, pow(3, 3, 2), (3 ** 3) % 2
(0, 0, 1, 1)
 max(<Список чисел через запятую>)
— максимальное значение из списка:
>>> max(1, 2, 3), max(3, 2, 3, 1), max(1, 1.0), max(1.0, 1)
(3, 3, 1, 1.0)
 min(<Список чисел через запятую>)
— минимальное значение из списка:
>>> min(1, 2, 3), min(3, 2, 3, 1), min(1, 1.0), min(1.0, 1)
(1, 1, 1, 1.0)
 sum(<Последовательность>[, <Начальное значение>])
— возвращает сумму значений элементов последовательности (списка, кортежа и пр.) плюс
<Начальное значение>
. Если второй параметр не указан, начальное значение принимается равным
0
. Если последова- тельность пустая, возвращается значение второго параметра:
>>> sum((10, 20, 30, 40)), sum([10, 20, 30, 40])
(100, 100)
>>> sum([10, 20, 30, 40], 2), sum([], 2)
(102, 2)

Глава 5. Числа
77
 divmod(x, y)
— возвращает кортеж из двух значений
(x // y, x % y)
:
>>> divmod(13, 2) # 13 == 6 * 2 + 1
(6, 1)
>>> 13 // 2, 13 % 2
(6, 1)
>>> divmod(13.5, 2.0) # 13.5 == 6.0 * 2.0 + 1.5
(6.0, 1.5)
>>> 13.5 // 2.0, 13.5 % 2.0
(6.0, 1.5)
Следует понимать, что все типы данных, поддерживаемые Python, представляют собой классы. Класс float
, представляющий вещественные числа, поддерживает следующие по- лезные методы:
 is_integer()
— возвращает
True
, если заданное вещественное число не содержит дроб- ной части, т. е. фактически представляет собой целое число:
>>> (2.0).is_integer()
True
>>> (2.3).is_integer()
False
 as_integer_ratio()
— возвращает кортеж из двух целых чисел, представляющих собой числитель и знаменатель дроби, которая соответствует заданному числу:
>>> (0.5).as_integer_ratio()
(1, 2)
>>> (2.3).as_integer_ratio()
(2589569785738035, 1125899906842624)
5.2. Модуль math: математические функции
Модуль math предоставляет дополнительные функции для работы с числами, а также стан- дартные константы. Прежде чем использовать модуль, необходимо подключить его с по- мощью инструкции: import math
П
РИМЕЧАНИЕ
Для работы с комплексными числами необходимо использовать модуль cmath.
Модуль math предоставляет следующие стандартные константы:
 pi
— число π:
>>> import math
>>> math.pi
3.141592653589793
 e
— константа e:
>>> math.e
2.718281828459045
Приведем перечень основных функций для работы с числами:
 sin()
, cos()
, tan()
— стандартные тригонометрические функции (синус, косинус, тан- генс). Значение указывается в радианах;

78
Часть I. Основы языка Python
 asin()
, acos()
, atan()
— обратные тригонометрические функции (арксинус, арккосинус, арктангенс). Значение возвращается в радианах;
 degrees()
— преобразует радианы в градусы:
>>> math.degrees(math.pi)
180.0
 radians()
— преобразует градусы в радианы:
>>> math.radians(180.0)
3.141592653589793
 exp()
— экспонента;
 log(<Число>[, <База>])
— логарифм по заданной базе. Если база не указана, вычисляет- ся натуральный логарифм (по базе e);
 log10()
— десятичный логарифм;
 log2()
— логарифм по базе 2;
 sqrt()
— квадратный корень:
>>> math.sqrt(100), math.sqrt(25)
(10.0, 5.0)
 ceil()
— значение, округленное до ближайшего большего целого:
>>> math.ceil(5.49), math.ceil(5.50), math.ceil(5.51)
(6, 6, 6)
 floor()
— значение, округленное до ближайшего меньшего целого:
>>> math.floor(5.49), math.floor(5.50), math.floor(5.51)
(5, 5, 5)
 pow(<Число>, <Степень>)
— возводит число в степень:
>>> math.pow(10, 2), 10 ** 2, math.pow(3, 3), 3 ** 3
(100.0, 100, 27.0, 27)
 fabs()
— абсолютное значение:
>>> math.fabs(10), math.fabs(-10), math.fabs(-12.5)
(10.0, 10.0, 12.5)
 fmod()
— остаток от деления:
>>> math.fmod(10, 5), 10 % 5, math.fmod(10, 3), 10 % 3
(0.0, 0, 1.0, 1)
 factorial()
— факториал числа:
>>> math.factorial(5), math.factorial(6)
(120, 720)
 fsum(<Список чисел>)
— возвращает точную сумму чисел из заданного списка:
>>> sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
0.9999999999999999
>>> fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
1.0

Глава 5. Числа
79
П
РИМЕЧАНИЕ
В этом разделе мы рассмотрели только основные функции. Чтобы получить полный список функций, обращайтесь к документации по модулю math.
5.3. Модуль random: генерирование случайных чисел
Модуль random позволяет генерировать случайные числа. Прежде чем использовать модуль, необходимо подключить его с помощью инструкции: import random
Приведем перечень его основных функций:
 random()
— возвращает псевдослучайное число от
0.0
до
1.0
:
>>> import random
>>> random.random()
0.9753144027290991
>>> random.random()
0.5468390487484339
>>> random.random()
0.13015058054767736
 seed([<Параметр>][, version=2])
— настраивает генератор случайных чисел на новую последовательность. Если первый параметр не указан, в качестве базы для случайных чисел будет использовано системное время. При одинаковых значениях первого пара- метра будет генерироваться одинаковая последовательность чисел:
>>> random.seed(10)
>>> random.random()
0.5714025946899135
>>> random.seed(10)
>>> random.random()
0.5714025946899135
 uniform(<Начало>, <Конец>)
— возвращает псевдослучайное вещественное число в диа- пазоне от
<Начало>
до
<Конец>
:
>>> random.uniform(0, 10)
9.965569925394552
>>> random.uniform(0, 10)
0.4455638245043303
 randint(<Начало>, <Конец>)
— возвращает псевдослучайное целое число в диапазоне от
<Начало>
до
<Конец>
:
>>> random.randint(0, 10)
4
>>> random.randint(0, 10)
10
 randrange([<Начало>, ]<Конец>[, <Шаг>])
— возвращает случайный элемент из созда- ваемого «за кадром» диапазона. Параметры аналогичны параметрам функции range()
:

80
Часть I. Основы языка Python
>>> random.randrange(10)
5
>>> random.randrange(0, 10)
2
>>> random.randrange(0, 10, 2)
6
 choice(<Последовательность>)
— возвращает случайный элемент из заданной последо- вательности (строки, списка, кортежа):
>>> random.choice("string") # Строка 'i'
>>> random.choice(["s", "t", "r"]) # Список 'r'
>>> random.choice(("s", "t", "r")) # Кортеж 't'
 shuffle(<Список>[, <Число от 0.0 до 1.0>])
— перемешивает элементы списка слу- чайным образом. Если второй параметр не указан, то используется значение, возвра- щаемое функцией random()
. Никакого результата при этом не возвращается:
>>> arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> random.shuffle(arr)
>>> arr
[8, 6, 9, 5, 3, 7, 2, 4, 10, 1]
 sample(<Последовательность>, <Количество элементов>)
— возвращает список из ука- занного количества элементов, которые будут выбраны случайным образом из заданной последовательности. В качестве таковой можно указать любые объекты, поддерживаю- щие итерации:
>>> random.sample("string", 2)
['i', 'r']
>>> arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> random.sample(arr, 2)
[7, 10]
>>> arr # Сам список не изменяется
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> random.sample((1, 2, 3, 4, 5, 6, 7), 3)
[6, 3, 5]
>>> random.sample(range(300), 5)
[126, 194, 272, 46, 71]
Для примера напишем функцию-генератор паролей произвольной длины (листинг 5.1). Для этого добавим в список arr все разрешенные символы, а далее в цикле будем получать случайный элемент с помощью функции choice()
. По умолчанию будет выдаваться пароль из 8 символов.
Листинг 5.1. Генератор паролей
# -*- coding: utf-8 -*- import random # Подключаем модуль random def passw_generator(count_char=8):

Глава 5. Числа
81 arr = ['a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L',
'M','N','O','P','Q','R','S','T','U','V', 'W',
'X','Y','Z','1','2','3','4','5','6','7','8','9','0'] passw = [] for i in range(count_char): passw.append(random.choice(arr)) return "".join(passw)
Испытаем эту функцию в действии: print(passw_generator(10)) # Выведет что-то вроде ngODHE8J8x print(passw_generator()) # Выведет что-то вроде ZxcpkF5O

ГЛ А В А
6
Строки и двоичные данные
Строки представляют собой последовательности символов. Длина строки ограничена лишь объемом оперативной памяти компьютера. Как и все последовательности, строки поддер- живают обращение к элементу по индексу, получение среза, конкатенацию (оператор
+
), повторение (оператор
*
), проверку на вхождение (операторы in и not in
).
Кроме того, строки относятся к неизменяемым типам данных. Поэтому практически все строковые методы в качестве значения возвращают новую строку. (При использовании не- больших строк это не приводит к каким-либо проблемам, но при работе с большими стро- ками можно столкнуться с проблемой нехватки памяти.) Иными словами, можно получить символ по индексу, но изменить его будет нельзя:
>>> s = "Python"
>>> s[0] # Можно получить символ по индексу 'P'
>>> s[0] = "J" # Изменить строку нельзя
Traceback (most recent call last):
File "
", line 1, in s[0] = "J" # Изменить строку нельзя
TypeError: 'str' object does not support item assignment
В некоторых языках программирования строка должна заканчиваться нулевым символом.
В языке Python нулевой символ может быть расположен внутри строки:
>>> "string\x00string" # Нулевой символ — это НЕ конец строки 'string\x00string'
Python поддерживает следующие строковые типы:
 str
— Unicode-строка. Обратите внимание, конкретная кодировка: UTF-8, UTF-16 или
UTF-32 — здесь не указана. Рассматривайте такие строки, как строки в некой абстракт- ной кодировке, позволяющие хранить символы Unicode и производить манипуляции с ними. При выводе Unicode-строку необходимо преобразовать в последовательность байтов в какой-либо кодировке:
>>> type("строка")

>>> "строка".encode(encoding="cp1251") b'\xf1\xf2\xf0\xee\xea\xe0'
>>> "строка".encode(encoding="utf-8") b'\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0'

Глава 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 str(obj1, "ascii", "strict")
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 s[10]
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 s[0] = "J" # Изменить строку нельзя
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

Глава 6. Строки и двоичные данные
93
• e
— вещественное число в экспоненциальной форме (буква e
в нижнем регистре):
>>> print("%e %e" % (3000, 18657.81452))
3.000000e+03 1.865781e+04

E
— вещественное число в экспоненциальной форме (буква
E
в верхнем регистре):
>>> print("%E %E" % (3000, 18657.81452))
3.000000E+03 1.865781E+04
• g
— эквивалентно f
или e
(выбирается более короткая запись числа):
>>> print("%g %g %g" % (0.086578, 0.000086578, 1.865E-005))
0.086578 8.6578e-05 1.865e-05

G
— эквивалентно f
или
E
(выбирается более короткая запись числа):
>>> print("%G %G %G" % (0.086578, 0.000086578, 1.865E-005))
0.086578 8.6578E-05 1.865E-05
Если внутри строки необходимо использовать символ процента, этот символ следует удво- ить, иначе будет выведено сообщение об ошибке:
>>> print("% %s" % ("- это символ процента")) # Ошибка
Traceback (most recent call last):
File "
", line 1, in print("% %s" % ("- это символ процента")) # Ошибка
TypeError: not all arguments converted during string formatting
>>> print("%% %s" % ("- это символ процента")) # Нормально
% — это символ процента
Форматирование строк очень удобно использовать при передаче данных в шаблон веб- страницы. Для этого заполняем словарь данными и указываем его справа от символа
%
, а сам шаблон — слева. Продемонстрируем это на примере (листинг 6.1).
Листинг 6.1. Пример использования форматирования строк
# -*- coding: utf-8 -*- html = """

1   ...   6   7   8   9   10   11   12   13   ...   83


написать администратору сайта