Лутц М. - Изучаем Python (1077325), страница 33
Текст из файла (страница 33)
Интерпретатор РуСЬоп ранжирует сложность числовых типов следующим образом: целые числа проще, чем длинные целые числа, которые проще чисел с плавающей точкой, которые в свою очередь проще комплексных чисел. Поэтому, когда в выражении участвуют целое число и число с плавающей точкой, как в предыдущем примере, то целое число сначала преобразуется в число с плавающей точкой и затем выполняется операция из математики чисел с плавающей точкой, что дает в результате число с плавающей точкой. Точно так же, когда один из операндов в выражении является комплексным числом, другой 149 Операторы выражений операнд преобразуется в комплексное число, и выражение дает в результате также комплексное число. Как будет показано далее в этом разделе, начиная с версии 2.2, интерпретатор Ру$Ьоп также автоматически преобразует целые числа в длинные целые, если их значения оказываются слишком большими, чтобы уместиться в формат простого целого числа.
Существует возможность принудительного преобразования типов с помощью встроенных функций: »> тпт(3, 1415) 3 »> т)оат(3) 3 0 »> )сод(4) 4( Однако в обычных ситуациях делать это не приходится, потому что Ру1)топ автоматически выполняет преобразование типов, и тип результата, как правило, соответствует вашим ожиданиям. Кроме того, имейте в виду, что все эти преобразования производятся только при смешивании числовых типов (то есть целых чисел и чисел с плавающей точкой) в математических операциях или в операциях сравнения. Вообще, РуФЬоп не вовлекает в преобразование другие типы. Например, попытка выполнить операцию сложения строки и числа приведет к появлению ошибки, если вы вручную не выполните преобразование типа одного из операндов — примеры таких преобразований встретятся вам в главе 7, когда мы будем обсуждать строки.
Обзор: перегрузка операторов Несмотря на то что сейчас в центре нашего внимания находятся встроенные числа, вы должны знать, что в языке Ру1Ьоп существует возможность выполнить (то есть реализовать) перегрузку любого оператора с помощью классов Руо)топ или расширений на языке С для работы с создаваемыми объектами.
Например, как будет показано позже, объекты, реализованные в виде классов, могут участвовать в операции сложения, индексироваться с помощью выражения [.'] и т. д. Кроме того, Ру(Д)оп сам автоматически перегружает некоторые операторы, чтобы с их помощью можно было выполнять различные действия, в зависимости от типа обрабатываемых встроенных объектов.
Например, оператор + выполняет операцию сложения, когда применяется к числам, но когда он применяется к последовательностям, таким как строки или списки, он выполняет операцию конкатенации. В действительности оператор + может выполнять любые действия, когда применяется к объектам, которые вы определяете с помощью классов.
Как было показано в предыдущей главе, эта особенность обычно называется полизторфизмом; термин означает, что выполняемая операция зависит от типов объектов-операндов, над которыми она выполняется. Глава 5. Числа Мы еще вернемся к этому понятию в главе 1б, когда будем рассматри- вать функции, потому что в этом контексте суть полиморфизма стано- вится более очевидной. Числа в действии Самый лучший способ понять числа и выражения состоит в том, чтобы увидеть их в действии. Давайте запустим интерактивный сеанс работы с интерпретатором и попробуем выполнить некоторые простые, но весьма показательные операции (если вы забыли, как запускается интерактивный сеанс, обращайтесь к главе 3). Переменные и основные выражения Прежде всего мы рассмотрим основные арифметические операции. В следующем упражнении выполняется присваивание целочисленных значений двум переменнььк (з и Ь), чтобы потом использовать их в более сложных выражениях.
Переменные — это всего лишь имена, создаваемые в языке РуФЬоп, которые используются для обозначения информации, сохраняемой в программах. Об этом мы будем говорить более подробно в следующей главе, а пока вы должны знать, что в языке Русйоп: ° Переменные создаются при выполнении операции присваивания значения. ° При вычислении выражений имена переменных замещаются их значениями. ° Прежде чем переменная сможет участвовать в выражениях, ей должно быть присвоено значение. ° Переменные именуют объекты и никогда не объявляются заранее.
Другими словами, следующие операции присваивания автоматически приводят к созданию переменных з и Ь: % рутбэл »> з = Э »> Ь = 4 я Создается яия Если зы прогоняете примеры на практике, зам не нужно вводить коммен- тарии, потому что они просто игнорируются интерпретатором Русйол и не являются необходимой частью инструкций, которые мы выполняем. Здесь я также использовал комментарий.
Вспомните, что в программном коде на языке РуЖоп текст, следующий за символом з, считается комментарием и игнорируется интерпретатором. Комментарии — это один из способов описать программный код на удобном для восприятия языке. Поскольку программный код, который пишется в ходе интерактивного сеанса, является временным, вам не требуется писать комментарии, я же буду добавлять их в примеры, чтобы объяснять работу программного кода.' В следующей части книги мы познакомимся 151 Числа в действии с еще одной похожей особенностью — со строками описания, которые включают текст комментариев в объекты.
А теперь попробуем использовать наши первые целочисленные объекты в выражениях. В настоящий момент переменные а и Ь все еще имеют значения 3 и 4, соответственно. Когда переменные, подобные этим, участвуют в выражении, они замещаются их значениями, и при работе в интерактивном режиме результат вычисления выражения тут же выводится на экран: * ° 2 С технической точки зрения результатами этих инструкций являются кортежи, состоящие из двух значений, потому что вводимые строки содержат по два выражения, разделенные запятыми. Именно по этой причине результаты отображаются в круглых скобках (подробнее о кортежах будет рассказываться позднее).
Следует заметить, что эти выражения выполняются беэ ошибок потому, что ранее переменным а и Ь были присвоены значения. Если использовать переменную, которой еще не было присвоено значение, РуФоп выведет сообщение об ошибке: »>с*2 Тгасеьаск (воат гесепт саы 1авт): 811Е скзтб1П>", 1>ПЕ 1, тл О машееггог паше 'с' 18 пот се(глеб В языке РуЬЬоп от вас не требуется заранее объявлять переменные, но прежде чем их можно будет использовать, им должны быть присвоены некоторые значения. На практике это означает, что перед тем, как к счетчикам можно будет прибавлять некоторые значения, их необходимо инициализировать нулевым значением; прежде чем к спискам можно будет добавлять новые элементы, их необходимо инициализировать пустыми списками, и т. д.
Ниже приводятся два немного более сложных выражения, чтобы проиллюстрировать порядок выполнения операторов и производимые преобразования: »>Ь/2+а № То ие, что и ((4 / 2) + 3) 5 »> рг1пт ь / (2. О + а) № то ме, что и (4 / (2 0 + 3)) 0 8 В первом выражении отсутствуют круглые скобки, поэтому интерпретатор Ру()топ автоматически группирует компоненты выражения »> а+1, а (4.
2) »>Ь ° 8, Ь (12, 2) »>аа2, Ь (1, 16) »> 2+ 4,0, (6.0, 16.0) - 1 № Сломение (3 ч Ц, вмчитвние (3 - 1) / 2 № Умномение (4 3), деление (4 / 2) № Деление ло модулю (остаток), возведение в степень 2.0 ° ° Ь № Смешивание типов, вмлолнлетсл преобразование 152 Глава 5. Числа в соответствии с правилами определения старшинства — оператор / находится ниже в табл. 5.2, чем оператор +, поэтому его приоритет считается выше и он выполняется первым. Результат вычисляется так, как если бы выражение включало скобки, как показано в комментарии, Кроме того, обратите внимание на то, что в первом выражении все числа являются целыми, поэтому интерпретатор выполняет целочисленные операции деления и сложения.
Во втором выражении круглые скобки окружают операцию сложения, чтобы вынудить интерпретатор выполнить ее в первую очередь (то есть перед оператором /). Кроме того, один из операндов является числом с плавающей точкой, т. к. в нем присутствует десятичная точка: 2. 0. Вследствие такого смешения типов перед выполнением операции сложения Ру()1оп преобразует целое число, на которое ссылается имя а, в число с плавающей точкой (3. 0).
Кроме того, он также преобразует значение переменной Ь в число с плавающей точкой (4. 0) и выполняет вещественное деление (4. 0 / 5. О), что в результате также дает число с плавающей точкой О. 8. Если бы в этом выражении участвовали только целые числа, была бы выполнена операция целочисленного деления (4 / 5) и результат был бы усечен до нуля (по крайней мере, в Ру()гоп 2.5; смотрите обсуждение истинного деления, которое следует далее). форматы отображения чисел Обратите внимание: в последнем примере была использована инструк- ция рг(лс. Вез этой инструкции результат мог бы показаться немного странным: № Автоматический вивод: виводится болишее ~испо циФР »> Ь / (2.0 + а) 0.80000000000000004 »> рг1пс ь / (2.0 + а) № инструкция ргапг отбрасивает лиенце цийри 0.8 »> 1/2.0 0.5 Причина появления такого, немного странного, результата кроется в ограничениях аппаратных средств, реализующих вещественную математику, и в невозможности обеспечить точное представление некоторых значений.
Обсуждение аппаратной архитектуры компьютера выходит далеко за рамки этой книги, тем не менее я замечу, что все цифры в первом результате действительно присутствуют в аппаратной части компьютера, выполняющей операции над числами с плавающей точкой, просто вы не привыкли видеть их. Я использовал этот пример, чтобы продемонстрировать различия в форматах отображения чисел— при автоматическом выводе результатов в ходе интерактивного сеанса отображается больше цифр, чем при использовании инструкции рг(л".. Однако надо заметить, что не всегда значения отображаются с таким большим числом цифр: 153 Чиспа в действии Форматы представления герг и юг С технической точки зрения различия между функцией автоматического вывода в интерактивной оболочке и инструкцией рг1п$ заключаются в различиях между встроенными функциями герт и зтг: »> герт(пцэ) № Используется для автоматического вывода: № в форме как есть '0.ЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗЗ1' »> втг(пцэ) № используется инструкцией ргтлт.
дружественная форма '0.333333333333' Обе функции преобразуют произвольные объекты в их строковое представление: герг (и функция автоматического вывода в интерактивной оболочке) выводит результаты в том виде, в каком они были получены; зт г (и инструкция рг(пт) обычно выполняет преобразование значения в более дружественное представление. Мы еще будем говорить об этом при обсуждении строк далее в книге, где вы найдете больше информации об этих встроенных функциях.