Как устроен Python. Как устроен Python. Харрисон. Харрисон Мэтт
Скачать 5.41 Mb.
|
60 Глава 7. Подробнее об объектах Рис. 7.4. Выполнение кода и анализ результатов в REPL в IDLE. Если вы не используете IDLE, узнайте, как это делается в вашем редакторе 7.5. Итоги В Python нет ничего, кроме объектов. Объекты обладают тремя свой- ствами: Тип — определяет класс для объекта. Значение — данные, содержащиеся в объекте. Проверяя два объекта на равенство ( == ), вы сравниваете их значения. Идентификатор — уникальный идентификатор объекта. В версии Python на сайте www.python.org идентификатор фактически опреде- ляет местонахождение объекта в памяти, которое является уникаль- ным значением. Когда вы проверяете два объекта на тождественность (оператором is ), вы проверяете, совпадают ли их идентификаторы. Вы также узнали, что изменяемые объекты (например, списки) могут изменять свое значение, тогда как неизменяемые объекты (например, строки и списки) изменяться «на месте» не могут. 7.6. Упражнения 61 7.6. Упражнения 1. Создайте переменную, которая указывает на число с плавающей точкой. Проанализируйте идентификатор, тип и значение этого числа. Обновите переменную, увеличив ее на 20. Снова проанали- зируйте идентификатор, тип и значение. Изменился ли идентифи- катор? Изменилось ли значение? 2. Создайте переменную, которая указывает на пустой список. Про- анализируйте идентификатор, тип и значение списка. Присоеди- ните к списку число 300. Снова проанализируйте идентификатор, тип и значение. Изменился ли идентификатор? Изменилось ли значение? 8 Числа В этой главе рассматриваются операции с числами в языке Python. В Python поддерживаются целые числа (такие, как −1, 5 или 2000) и числа с плавающей точкой (приближенное компьютерное представление таких чисел, как 0,333, 0,5 или −1000,234); они позволяют легко выполнять числовые операции. Изначально в Python предусмотрена поддержка опе- раций сложения, вычитания, умножения, деления, возведения в степень, вычисления остатка и многих других операций! В отличие от других языков, в Python существуют только объекты — это относится и к числам. Целые числа относятся к классу int : >>> type(1) Числа с плавающей точкой относятся к классу float : >>> type(2.0) Точность представления нецелых чисел ограничена. Пользователь дол- жен сам определить, достаточно ли ее для его текущих вычислений. Во внутреннем представлении чисел с плавающей точкой Python исполь- зует двоичное представление (соответствующее стандарту IEEE 754 для чисел с плавающей точкой). У чисел с плавающей точкой существует определенный порог точности, поэтому возможна погрешность округле- ния. Собственно, разработчик всегда должен ожидать, что вычисления выполняются с погрешностью округления. (Если вам потребуется более 8.1. Сложение 63 высокая точность, модуль decimal предоставляет более точную, хотя и более медленную реализацию.) Рассмотрим точность представления на простом примере. Что проис- ходит при выполнении простой на первый взгляд операции вычитания? >>> print(1.01 - .99) 0.020000000000000018 СОВЕТ Если вам захочется больше узнать о числах с плавающей точкой и их пред- ставлении в памяти компьютера, в Википедии 1 имеется более подробная информация по теме. 8.1. Сложение Python REPL может использоваться как простейший калькулятор. Чтобы сложить два целых числа, введите выражение: >>> 2 + 6 8 ПРИМЕЧАНИЕ В этом примере результат не связывается с переменной. Для вывода результа- та простейшего вычисления на терминал этого может быть достаточно. Если результат вдруг понадобится вам позднее, интерпретатор Python сохраняет последний результат в переменной с именем _ : >>> 2 + 6 8 >>> result = _ >>> result 8 При сложении двух целых чисел будет получено целое число. Аналогич- ным образом можно сложить два числа с плавающей точкой: >>> .4+.01 0.41000000000000003 1 https://ru.wikipedia.org/wiki/Число_с_плавающей_запятой 64 Глава 8. Числа Этот пример снова показывает, почему при работе с числами с плавающей точкой необходима осторожность: операции могут приводить к потере точности (настоящий результат равен 0,41). А что произойдет при сложении целого числа с числом с плавающей точкой? >>> 6 + .2 6.2 Python решает, что, поскольку вы складываете целое число с числом с плавающей точкой, вам нужна арифметическая операция с плавающей точкой. В данном случае Python автоматически преобразует 6 в число с плавающей точкой перед тем, как складывать его с .2 . Python возвра- щает результат в формате с плавающей точкой. ПРИМЕЧАНИЕ Если в операции используются два числовых операнда, преобразование обычно работает правильно. Для операций, в которых задействовано целое число и число с плавающей точкой, целое число преобразуется в формат с плавающей точкой. ПРИМЕЧАНИЕ Преобразования между строками и числами не выполняются для большин- ства математических операций. У правила есть два исключения: оператор форматирования строки и оператор умножения. При использовании % со строкой в левой части (левый операнд) и любым объ- ектом (включая числа) в правой части (правый операнд) Python выполняет операцию форматирования: >>> print('num: %s' % 2) num: 2 Если левый операнд является строкой, то при применении оператора умно- жения * Python выполняет повторение: >>> 'Python!' * 2 'Python!Python!' >>> '4' * 2 '44' 8.3. Умножение 65 ПРИМЕЧАНИЕ С классами int и float могут выполняться явные преобразования (несмотря на внешнее сходство с функциями, в действительности это классы): >>> int(2.3) 2 >>> float(3) 3.0 8.2. Вычитание Вычитание имеет много общего с умножением. При вычитании двух целых чисел или двух чисел с плавающей точкой будет получено целое число или число с плавающей точкой соответственно. Для смешанных числовых типов перед вычитанием выполняется преобразование опе- рандов: >>> 2 - 6 -4 >>> .25 - 0.2 0.04999999999999999 >>> 6 - .2 5.8 8.3. Умножение Во многих языках программирования символ * (звездочка) используется для умножения. Вероятно, вы и сами догадаетесь, что произойдет при умножении двух целых чисел: >>> 6 * 2 12 Если вы внимательно читали, то уже знаете, что происходит при умно- жении двух чисел с плавающей точкой: >>> .25 * 12.0 3.0 66 Глава 8. Числа А при смешанных типах в произведении будет получен результат с пла- вающей точкой: >>> 4 * .3 1.2 Результат с плавающей точкой в этих примерах выглядит пра- вильным. Тем не менее будьте внимательны и помните о проблемах с погрешностью представления — не стоит полагать, что вам всегда будет везти. 8.4. Деление В Python (как и во многих языках) знак / обозначает деление: >>> 12 / 4 3.0 В Python 3 также решена проблема, которую в предыдущих версиях Python многие считали дефектом. Результат деления двух целых чисел является числом с плавающей точкой: >>> 3 / 4 0.75 Прежде в Python выполнялось целочисленное деление. Если вам ну- жен именно такой вариант поведения, используйте оператор // . Какое целое число использует Python? Результат округления в меньшую сторону: >>> 3 // 4 0 8.5. Остаток Оператор % вычисляет остаток от целочисленного деления. Например, с его помощью можно проверить число на четность (или узнать, были ли обработаны 1000 элементов списка): 8.5. Остаток 67 # Остаток от деления 4 на 3 >>> 4 % 3 1 >>> 3 % 2 # нечетно, если результат равен 1 1 >>> 4 % 2 # четно, если результат равен 0 0 СОВЕТ Будьте внимательны при использовании оператора % с отрицательными числами. Поведение оператора изменяется в зависимости от того, какой из операндов отрицателен. Понятно, что при отсчете в обратном направлении остаток должен повторяться с определенной периодичностью: >>> 3 % 3 0 >>> 2 % 3 2 >>> 1 % 3 1 >>> 0 % 3 0 Какой результат должен быть получен при вычислении -1 % 3 ? Так как от- счет ведется в обратном направлении, результат снова должен быть равен 2: >>> -1 % 3 2 Но если изменить знак делителя, происходит нечто странное: >>> -1 % -3 -1 Python гарантирует, что знак результата совпадает со знаком делителя (или равен 0). Чтобы окончательно запутать вас, еще один пример: >>> 1 % -3 -2 Мораль: пожалуй, вам не стоит вычислять остаток с отрицательным делите- лем — только если вы твердо уверены в том, что вам действительно нужно именно это. 68 Глава 8. Числа 8.6. Возведение в степень Python также поддерживает оператор возведения в степень ** (две звез- дочки). Если вы хотите возвести 4 в квадрат (4 — основание, 2 — пока- затель степени), это делается так: >>> 4 ** 2 16 Результаты операции возведения в степень обычно стремительно увели- чиваются. Допустим, вы хотите возвести 10 в 100-ю степень: >>> 10 ** 100 10000000000000000000000000000000000000 00000000000000000000000000000000000000 0000000000000000000000000 Для хранения целых чисел программам требуется определенный объем памяти. Так как целые числа обычно относительно невелики, Python оптимизирует затраты памяти, чтобы избежать ее непроизводительного расходования. Во внутренней реализации «системные» целые числа мо- гут быть преобразованы в длинные целые для хранения больших чисел. Python 3 делает это за вас автоматически. Представьте шкалу пружинных весов. Если вы всегда взвешиваете мелкие предметы, вам будут удобны весы с короткой шкалой. Если вы торгуете песком, вероятно, песок будет удобно насыпать в мешки, чтобы с ними было удобнее работать. Вы будете держать под рукой небольшие мешки, чтобы использовать их для взвешивания. Но если время от времени вам приходится взвешивать большие предметы, выходящие за короткую шкалу, придется доставать большие весы и большой мешок. Было бы неразумно ис- пользовать большой мешок и большие весы для многих мелких предметов. Точно так же Python старается оптимизировать память для хранения целых чисел, ориентируясь на небольшие размеры. Если целое число не поме- щается в малый блок памяти (мешок), Python преобразует его в большое целое. На самом деле это желательное поведение, потому что в некоторых средах ошибка переполнения приводит к аварийному завершению програм- мы (или PacMan отказывается переходить на уровни выше 255, потому что счетчик уровня хранится в виде 8-разрядного числа). 8.9. Итоги 69 ПРИМЕЧАНИЕ Python включает модуль operator с функциями для основных математиче- ских операций. В частности, он пригодится вам при использовании таких расширенных возможностей Python, как лямбда-функции или генераторы списков: >>> import operator >>> operator.add(2, 4) # same as 2 + 4 6 8.7. Порядок операций При выполнении математических вычислений не все операции вы- полняются слева направо. Например, операции сложения и вычитания выполняются после операций умножения и деления. Компьютеры ра- ботают по тем же правилам. Если вы хотите, чтобы операции сложения (или вычитания) выполнялись в первую очередь, используйте круглые скобки для обозначения порядка операций: >>> 4 + 2 * 3 10 >>> (4 + 2) * 3 18 Как следует из примера, выражение в круглых скобках вычисляется в первую очередь. 8.8. Другие операции Справочный раздел REPL весьма полезен. В нем имеется тема NUMBERMETHODS , объясняющая, как работают все числовые операции. 8.9. Итоги В Python имеется встроенная поддержка основных математических опе- раций. Разумеется, язык поддерживает сложение, вычитание, умножение и деление. Кроме того, доступны операции возведения в степень и вычис- 70 Глава 8. Числа ления остатка. Если вам понадобится управлять порядком выполнения операций, заключите ту операцию, которая должна выполняться первой, в круглые скобки. Если вам нужно провести простые вычисления, вместо запуска приложения-калькулятора можно выполнить их в Python. Воз- можности языка более чем достаточны для большинства задач. 8.10. Упражнения 1. В эту неделю вы спали 6,2, 7, 8, 5, 6,5, 7,1 и 8,5 часа. Вычислите сред- нюю продолжительность сна в часах. 2. Делится ли число 297 без остатка на 3? 3. Чему равен результат возведения 2 в десятую степень? 4. В Википедии 1 високосный год определяется следующим образом: «…високосным оставался год, номер которого кратен четырем, но исключение делалось для тех, которые были кратны 100. Такие годы были високосными только тогда, когда делились еще и на 400… Так, годы 1700, 1800 и 1900 не являются високосными, так как они кратны 100 и не кратны 400. Годы 1600 и 2000 — високосные». Напишите код Python, который определяет, являются ли високосными годы 1800, 1900, 1903, 2000 и 2002. 1 https://ru.wikipedia.org/wiki/Високосный_год 9 Строки Строки представляют собой неизменяемые объекты для хранения сим- вольных данных. Строка может содержать один символ, слово, после- довательность слов, абзац, несколько абзацев, хотя может не содержать ни одного символа. В Python строки заключаются между символами ' (одинарные кавычки), " (двойные кавычки), """ (тройные двойные кавычки) или ''' (тройные одинарные кавычки). Несколько примеров: >>> character = 'a' >>> name = 'Matt' >>> with_quote = "I ain't gonna" >>> longer = """This string has ... multiple lines ... in it""" >>> latin = '''Lorum ipsum ... dolor''' >>> escaped = 'I ain\'t gonna' >>> zero_chars = '' >>> unicode_snake = "I love \N{SNAKE}" Обратите внимание: строки всегда начинаются и завершаются кавычками одного типа. Как показано в примере with_quote , одинарные кавычки мо- гут находиться внутри строк, заключенных в двойные кавычки, и наобо- рот. Кроме того, если вам понадобится включить в строку кавычку того же типа, ее можно экранировать символом \ (обратная косая черта). При выводе экранированного символа обратная косая черта игнорируется. 72 Глава 9. Строки ПРИМЕЧАНИЕ У наблюдательного читателя может возникнуть вопрос — как включить в строку символ обратной косой черты? Чтобы включить обратную косую черту в обычную строку, ее необходимо экранировать… да, все верно — еще одной обратной косой чертой: >>> backslash = '\\' >>> print(backslash) \ ПРИМЕЧАНИЕ Несколько стандартных способов экранирования символов в Python: Экранирующая последовательность Вывод \\ Обратная косая черта \' Одинарная кавычка \" Двойная кавычка \b ASCII-символ Backspace \n Новая строка \t Табуляция \u12af 16-разрядный символ Юникода \U12af89bc 32-разрядный символ Юникода \N{SNAKE} Символ Юникода \o84 Символ в восьмеричной кодировке \xFF Шестнадцатеричный символ СОВЕТ Если вы не хотите применять экранирование, используйте необработан- ные (raw) строки, поставив перед строкой префикс r . Необработанные строки обычно встречаются в двух местах. Они используются в регуляр- ных выражениях, в которых обратная косая черта также используется как экранирующий символ. Регулярные выражения применяются для поиска символов в тексте по шаблону (например, телефонных номеров, имен и т. д.). Модуль re из стандартной библиотеки Python предоставляет поддержку Строки 73 регулярных выражений. Кроме того, необработанные строки также ис- пользуются в путях Windows, где обратная косая черта интерпретируется как разделитель. В необработанных строках символы интерпретируются буквально (то есть без всякого экранирования). Следующий пример демонстрирует различия между необработанными и обычными строками: >>> slash_t = r'\tText \\' >>> print(slash_t) \tText \\ >>> normal = '\tText \\' >>> print(normal) Text \ В Python также предусмотрен механизм тройных кавычек для опреде- ления строк. Тройные кавычки удобны для создания строк, разделенных на абзацы. Кроме того, строки в тройных кавычках часто используются в строках документации. Строки документации будут рассматриваться в главе, посвященной функциям. Ниже приведен пример строки в трой- ных кавычках: >>> paragraph = """Lorem ipsum dolor ... sit amet, consectetur adipisicing ... elit, sed do eiusmod tempor incididunt ... ut labore et dolore magna aliqua. Ut ... enimad minim veniam, quis nostrud ... exercitation ullamco laboris nisi ut ... aliquip ex ea commodo consequat. Duis ... aute irure dolor in reprehenderit in ... voluptate velit esse cillum dolore eu ... fugiat nulla pariatur. Excepteur sint ... occaecat cupidatat non proident, sunt ... in culpa qui officia deserunt mollit ... anim id est laborum.""" Строки в тройных кавычках удобны тем, что в них можно вставлять одинарные и двойные кавычки без экранирования: >>> """This string has double " and single ... quotes ' inside of it""" 'This string has double " and single\nquotes \' inside of it' 74 Глава 9. Строки Впрочем, если кавычки приходятся на конец строки, последнюю кавычку в тексте необходимо экранировать: >>> """He said, "Hello"""" File " """He said, "Hello"""" ^ SyntaxError: EOL while scanning string literal >>> """He said, "Hello\"""" 'He said, "Hello"' 9.1. Форматирование строк Хранить строки в переменных удобно, но необходимо также иметь воз- можность собирать строки из других строк и выполнять с ними нужные манипуляции. Для этой цели можно воспользоваться механизмом фор- матирования строк. В Python 3 предпочтительным способом форматирования считается использование метода .format . В следующем примере мы приказываем Python заменить {} (заполнитель) содержимым переменной name , то есть строкой Matt : >>> name = 'Matt' >>> print('Hello {}'.format(name)) Hello Matt Другое полезное свойство форматирования заключается в том, что форматировать также можно нестроковые объекты — например, числа: >>> print('I:{} R:{} S:{}'.format(1, 2.5, 'foo')) I:1 R:2.5 S:foo |