Математический анализ. 3е издание
Скачать 4.86 Mb.
|
Смешивание типов и их преобразование Помимо смешивания операторов вы можете также смешивать различ ные числовые типы. Например, вы хотите найти сумму целого числа и числа с плавающей точкой: 40 + 3.14 Но это влечет за собой другой вопрос: какого типа будет результат – целое число или число с плавающей точкой? Ответ прост, особенно для тех, кто уже имеет опыт работы с любыми другими языками програм мирования: в выражениях, где участвуют значения различных типов, интерпретатор сначала выполняет преобразование типов операндов к типу самого сложного операнда, а потом применяет математику, специфичную для этого типа. Если вам уже приходилось использовать язык C, вы найдете, что такое поведение соответствует порядку преоб разования типов в этом языке. Интерпретатор Python ранжирует сложность числовых типов следую щим образом: целые числа проще, чем длинные целые числа, которые проще чисел с плавающей точкой, которые в свою очередь проще ком плексных чисел. Поэтому, когда в выражении участвуют целое число и число с плавающей точкой, как в предыдущем примере, то целое число сначала преобразуется в число с плавающей точкой и затем вы полняется операция из математики чисел с плавающей точкой, что да ет в результате число с плавающей точкой. Точно так же, когда один из операндов в выражении является комплексным числом, другой Операторы выражений 149 операнд преобразуется в комплексное число, и выражение дает в ре зультате также комплексное число. Как будет показано далее в этом разделе, начиная с версии 2.2, интерпретатор Python также автомати чески преобразует целые числа в длинные целые, если их значения оказываются слишком большими, чтобы уместиться в формат просто го целого числа. Существует возможность принудительного преобразования типов с по мощью встроенных функций: >>> int(3.1415) 3 >>> float(3) 3.0 >>> long(4) 4L Однако в обычных ситуациях делать это не приходится, потому что Python автоматически выполняет преобразование типов, и тип резуль тата, как правило, соответствует вашим ожиданиям. Кроме того, имейте в виду, что все эти преобразования производятся только при смешивании числовых типов (то есть целых чисел и чисел с плавающей точкой) в математических операциях или в операциях сравнения. Вообще, Python не вовлекает в преобразование другие ти пы. Например, попытка выполнить операцию сложения строки и чис ла приведет к появлению ошибки, если вы вручную не выполните пре образование типа одного из операндов – примеры таких преобразова ний встретятся вам в главе 7, когда мы будем обсуждать строки. Обзор: перегрузка операторов Несмотря на то что сейчас в центре нашего внимания находятся встро енные числа, вы должны знать, что в языке Python существует воз можность выполнить (то есть реализовать) перегрузку любого операто ра с помощью классов Python или расширений на языке C для работы с создаваемыми объектами. Например, как будет показано позже, объ екты, реализованные в виде классов, могут участвовать в операции сложения, индексироваться с помощью выражения [i] и т. д. Кроме того, Python сам автоматически перегружает некоторые опера торы, чтобы с их помощью можно было выполнять различные дейст вия, в зависимости от типа обрабатываемых встроенных объектов. На пример, оператор + выполняет операцию сложения, когда применяет ся к числам, но когда он применяется к последовательностям, таким как строки или списки, он выполняет операцию конкатенации. В дей ствительности оператор + может выполнять любые действия, когда применяется к объектам, которые вы определяете с помощью классов. Как было показано в предыдущей главе, эта особенность обычно назы вается полиморфизмом; термин означает, что выполняемая операция зависит от типов объектовоперандов, над которыми она выполняется. 150 Глава 5. Числа Мы еще вернемся к этому понятию в главе 15, когда будем рассматри вать функции, потому что в этом контексте суть полиморфизма стано вится более очевидной. Числа в действии Самый лучший способ понять числа и выражения состоит в том, чтобы увидеть их в действии. Давайте запустим интерактивный сеанс работы с интерпретатором и попробуем выполнить некоторые простые, но весьма показательные операции (если вы забыли, как запускается ин терактивный сеанс, обращайтесь к главе 3). Переменные и основные выражения Прежде всего мы рассмотрим основные арифметические операции. В следующем упражнении выполняется присваивание целочисленных значений двум переменным (a и b), чтобы потом использовать их в более сложных выражениях. Переменные – это всего лишь имена, создавае мые в языке Python, которые используются для обозначения информа ции, сохраняемой в программах. Об этом мы будем говорить более под робно в следующей главе, а пока вы должны знать, что в языке Python: • Переменные создаются при выполнении операции присваивания значения. • При вычислении выражений имена переменных замещаются их значениями. • Прежде чем переменная сможет участвовать в выражениях, ей должно быть присвоено значение. • Переменные именуют объекты и никогда не объявляются заранее. Другими словами, следующие операции присваивания автоматически приводят к созданию переменных a и b: % python >>> a = 3 # Создается имя >>> b = 4 Здесь я также использовал комментарий. Вспомните, что в программ ном коде на языке Python текст, следующий за символом #, считается комментарием и игнорируется интерпретатором. Комментарии – это один из способов описать программный код на удобном для воспри ятия языке. Поскольку программный код, который пишется в ходе интерактивного сеанса, является временным, вам не требуется писать комментарии, я же буду добавлять их в примеры, чтобы объяснять ра боту программного кода. 1 В следующей части книги мы познакомимся 1 Если вы прогоняете примеры на практике, вам не нужно вводить коммен тарии, потому что они просто игнорируются интерпретатором Python и не являются необходимой частью инструкций, которые мы выполняем. Числа в действии 151 с еще одной похожей особенностью – со строками описания, которые включают текст комментариев в объекты. А теперь попробуем использовать наши первые целочисленные объек ты в выражениях. В настоящий момент переменные a и b все еще име ют значения 3 и 4, соответственно. Когда переменные, подобные этим, участвуют в выражении, они замещаются их значениями, и при рабо те в интерактивном режиме результат вычисления выражения тут же выводится на экран: >>> a + 1, a 1 # Сложение (3 + 1), вычитание (3 1) (4, 2) >>> b * 3, b / 2 # Умножение (4 * 3), деление (4 / 2) (12, 2) >>> a % 2, b ** 2 # Деление по модулю (остаток), возведение в степень (1, 16) >>> 2 + 4.0, 2.0 ** b # Смешивание типов, выполняется преобразование (6.0, 16.0) С технической точки зрения результатами этих инструкций являются кортежи , состоящие из двух значений, потому что вводимые строки со держат по два выражения, разделенные запятыми. Именно по этой при чине результаты отображаются в круглых скобках (подробнее о корте жах будет рассказываться позднее). Следует заметить, что эти выраже ния выполняются без ошибок потому, что ранее переменным a и b были присвоены значения. Если использовать переменную, которой еще не было присвоено значение, Python выведет сообщение об ошибке: >>> c * 2 Traceback (most recent call last): File " NameError: name 'c' is not defined В языке Python от вас не требуется заранее объявлять переменные, но прежде чем их можно будет использовать, им должны быть присвоены некоторые значения. На практике это означает, что перед тем, как к счетчикам можно будет прибавлять некоторые значения, их необхо димо инициализировать нулевым значением; прежде чем к спискам можно будет добавлять новые элементы, их необходимо инициализи ровать пустыми списками, и т. д. Ниже приводятся два немного более сложных выражения, чтобы про иллюстрировать порядок выполнения операторов и производимые преобразования: >>> b / 2 + a # То же, что и ((4 / 2) + 3) 5 >>> print b / (2.0 + a) # То же, что и (4 / (2.0 + 3)) 0.8 В первом выражении отсутствуют круглые скобки, поэтому интер претатор Python автоматически группирует компоненты выражения 152 Глава 5. Числа в соответствии с правилами определения старшинства – оператор / на ходится ниже в табл. 5.2, чем оператор +, поэтому его приоритет счита ется выше и он выполняется первым. Результат вычисляется так, как если бы выражение включало скобки, как показано в комментарии. Кроме того, обратите внимание на то, что в первом выражении все чис ла являются целыми, поэтому интерпретатор выполняет целочислен ные операции деления и сложения. Во втором выражении круглые скобки окружают операцию сложения, чтобы вынудить интерпретатор выполнить ее в первую очередь (то есть перед оператором /). Кроме того, один из операндов является числом с плавающей точкой, т. к. в нем присутствует десятичная точка: 2.0. Вследствие такого смешения типов перед выполнением операции сло жения Python преобразует целое число, на которое ссылается имя a, в число с плавающей точкой (3.0). Кроме того, он также преобразует значение переменной b в число с плавающей точкой (4.0) и выполняет вещественное деление (4.0 / 5.0), что в результате также дает число с плавающей точкой 0.8. Если бы в этом выражении участвовали толь ко целые числа, была бы выполнена операция целочисленного деления (4 / 5) и результат был бы усечен до нуля (по крайней мере, в Python 2.5; смотрите обсуждение истинного деления, которое следует далее). Форматы отображения чисел Обратите внимание: в последнем примере была использована инструк ция print. Без этой инструкции результат мог бы показаться немного странным: >>> b / (2.0 + a) # Автоматический вывод: выводится большее число цифр 0.80000000000000004 >>> print b / (2.0 + a) # Инструкция print отбрасывает лишние цифры 0.8 Причина появления такого, немного странного, результата кроется в ограничениях аппаратных средств, реализующих вещественную ма тематику, и в невозможности обеспечить точное представление неко торых значений. Обсуждение аппаратной архитектуры компьютера выходит далеко за рамки этой книги, тем не менее я замечу, что все цифры в первом результате действительно присутствуют в аппаратной части компьютера, выполняющей операции над числами с плавающей точкой, просто вы не привыкли видеть их. Я использовал этот пример, чтобы продемонстрировать различия в форматах отображения чисел – при автоматическом выводе результатов в ходе интерактивного сеанса отображается больше цифр, чем при использовании инструкции print. Однако надо заметить, что не всегда значения отображаются с таким большим числом цифр: >>> 1 / 2.0 0.5 Числа в действии 153 и что кроме применения инструкции print и автоматического вывода результатов существуют и другие способы отображения чисел: >>> num = 1 / 3.0 >>> num # Автоматический вывод 0.33333333333333331 >>> print num # Инструкция print выполняет округление 0.333333333333 >>> "%e" % num # Вывод с использованием строки форматирования '3.333333e001' >>> "%2.2f" % num # Вывод с использованием строки форматирования '0.33' В последних двух случаях была использована строка форматирова+ ния результата выражения, которая позволяет гибко определять фор мат представления, но об этом мы поговорим в главе 7, когда займемся исследованием строк. Деление: классическое, с округлением вниз и истинное Теперь, когда вы увидели, как работает операция деления, вы должны знать, что она претерпит небольшие изменения в будущей версии Py thon (версия 3.0, которая должна появиться после выпуска этого изда ния книги). В Python 2.5 она работает так, как только что было описа но, но фактически существуют два оператора деления (один из кото рых претерпит изменения): Форматы представления repr и str C технической точки зрения различия между функцией автома тического вывода в интерактивной оболочке и инструкцией print заключаются в различиях между встроенными функциями repr и str: >>> repr(num) # Используется для автоматического вывода: # в форме как есть '0.33333333333333331' >>> str(num) # Используется инструкцией print: дружественная форма '0.333333333333' Обе функции преобразуют произвольные объекты в их строковое представление: repr (и функция автоматического вывода в инте рактивной оболочке) выводит результаты в том виде, в каком они были получены; str (и инструкция print) обычно выполняет преобразование значения в более дружественное представление. Мы еще будем говорить об этом при обсуждении строк далее в книге, где вы найдете больше информации об этих встроенных функциях. 154 Глава 5. Числа X / Y Классическое деление. В Python 2.5 и в более ранних версиях ре зультат усекается при делении целых чисел и сохраняется дробная часть для чисел с плавающей точкой. Этот оператор станет операто ром истинного деления – в будущей версии Python 3.0 он будет все гда сохранять дробную часть, независимо от типов операндов. X // Y Деление с округлением вниз. Этот оператор впервые появился в Py thon 2.2. Он всегда отсекает дробную часть, округляя результат до ближайшего наименьшего целого, независимо от типов операндов. Деление с округлением вниз было добавлено по той причине, что в те кущей модели классического деления тип результата зависит от типов операндов, который трудно предсказать заранее в языках программи рования с динамической типизацией, таких как Python. Изза возможных проблем с обратной совместимостью операция деле ния в языке Python в настоящее время находится в состоянии постоян ного изменения. Подытоживая вышесказанное: в версии 2.5 оператор деления / по умолчанию работает, как было описано выше, а оператор деления с округлением вниз // может использоваться для округления результата деления до ближайшего наименьшего целого, независимо от типов операндов: >>> (5 / 2), (5 / 2.0), (5 / 2.0), (5 / 2) (2, 2.5, 2.5, 3) >>> (5 // 2), (5 // 2.0), (5 // 2.0), (5 // 2) (2, 2.0, 3.0, 3) >>> (9 / 3), (9.0 / 3), (9 // 3), (9 // 3.0) (3, 3.0, 3, 3.0) В будущей версии Python оператор / изменится так, что будет возвра щать истинный результат деления, который всегда будет содержать дробную часть, даже в случае деления целых чисел, например, резуль татом выражения 1 / 2 будет значение 0.5, а не 0, в то время как резуль татом выражения 1 // 2 будет значение 0. А сейчас, пока эти изменения еще не включены полностью, ознако миться с будущим принципом действия оператора / можно при исполь зовании специальной формы импорта: from __future__ import division. В этом случае оператор / превращается в оператор истинного деления (с сохранением дробной части в результате), а принцип действия опера тора // остается неизменным. Ниже показано, как эти операторы будут действовать в будущем: >>> from _ _future_ _ import division >>> (5 / 2), (5 / 2.0), (5 / 2.0), (5 / 2) (2.5, 2.5, 2.5, 2.5) Числа в действии 155 >>> (5 // 2), (5 // 2.0), (5 // 2.0), (5 // 2) (2, 2.0, 3.0, 3) >>> (9 / 3), (9.0 / 3), (9 // 3), (9 // 3.0) (3.0, 3.0, 3, 3.0) Рассмотрите простой пример цикла while в главе 13 и соответствующее упражнение в конце четвертой части книги, которые иллюстрируют программный код, на котором может сказаться это изменение в пове дении оператора /. Вообще, воздействию этого изменения может быть подвержен любой программный код, который подразумевает усечение дробной части в целочисленном результате (в этих случаях вместо него следует использовать оператор //). К моменту написания этих строк данное изменение планируется включить в версию Python 3.0, но вам обязательно следует опробовать эти выражения в своей версии интер претатора, чтобы увидеть, как этот оператор действует. Кроме того, за помните специальную команду from, использованную здесь, – она еще будет обсуждаться в главе 21. Битовые операции Помимо обычных числовых операций (сложение, вычитание и т. д.) язык Python поддерживает большую часть видов числовых выраже ний, доступных в языке C. Например, ниже приводится пример вы полнения операций поразрядного сдвига и логических операций: >>> x = 1 # 0001 >>> x << 2 # Сдвиг влево на 2 бита: 0100 4 >>> x | 2 # Побитовое ИЛИ: 0011 3 >>> x & 1 # Побитовое И: 0001 1 В первом выражении двоичное значение 1 (по основанию 2, 0001) сдви гается влево на две позиции, в результате получается число 4 (0100). В последних двух выражениях выполняются двоичная операция ИЛИ (0001|0010 = 0011) и двоичная операция И (0001&0001 = 0001). Такого рода операции позволяют хранить сразу несколько флагов и других значе ний в единственном целом числе. Мы не будем здесь слишком углубляться в «жонглирование битами». Вам пока достаточно знать, что битовые операции поддерживаются языком, и они могут пригодиться, когда вы будете иметь дело, напри мер, с сетевыми пакетами или упакованными двоичными данными, ко торые производятся программами на языке C. Тем не менее вы должны понимать, что в языках высокого уровня, таких как Python, битовые операции не имеют такого большого значения, как в низкоуровневых языках, подобных языку C. Как правило, если у вас возникает желание использовать битовые операции в программах на языке Python, вам не обходимо вспомнить, на каком языке вы программируете. В Python |