Программирование на Python 3. Руководство издательство СимволПлюс
Скачать 3.74 Mb.
|
«Золотой запас» Python В этом разделе мы узнаем о восьми ключевых составляющих языка Python, а в следующем разделе увидим, как используются эти состав ляющие на примере пары маленьких, но практичных программ. Обсу ждение описываемых здесь тем ведется не только в этой главе, поэтому, если вы почувствуете, что информации не хватает или чтото выглядит слишком громоздко, воспользуйтесь ссылками вперед, содержанием или предметным указателем; практически всегда обнаружится, что Py thon предоставляет нужную вам особенность, к тому же в более краткой и выразительной форме, чем показано здесь, и, кроме того, обнаружит ся еще много чего вокруг. 28 Глава 1. Быстрое введение в процедурное программирование Составляющая №1: типы данных Одна из фундаментальных особенностей любого языка программиро вания заключается в способности представлять элементы данных. Язык Python предоставляет несколько встроенных типов данных, но пока интерес для нас представляют только два из них. В языке Python для представления целых чисел (положительных и отрицательных) используется тип int, а для представления строк (последовательностей символов Юникода) используется тип str. Ниже приводятся несколь ко примеров литералов целых чисел и строк: 973 210624583337114373395836055367340864637790190801098222508621955072 0 "Infinitely Demanding" 'Simon Critchley' 'positively αβγ€÷©' '' Между прочим, второе число в этом примере – это число 2 217 – размер целых чисел в языке Python ограничивается только объемом памяти, имеющейся в компьютере, а не фиксированным числом байтов. Стро ки могут ограничиваться кавычками или апострофами при условии, что с обоих концов используются однотипные кавычки, а поскольку для представления строк Python использует Юникод, строки могут со держать не только символы из набора ASCII, как показано в предпо следней строке примера. Пустые строки – это просто кавычки, внутри которых ничего нет. Для доступа к элементам последовательностей, таким как символы в строках, в языке Python используются квадратные скобки ([]). На пример, находясь в командной оболочке Python (когда интерпретатор запущен в интерактивном режиме или в среде IDLE) мы можем ввести следующее – вывод командной оболочки Python выделен жирным шриф том, а то, что вводится с клавиатуры – обычным моноширинным шрифтом: >>> "Hard Times"[5] 'T' >>> "giraffe"[0] 'g' Традиционно в командной оболочке Python строка приглашения к вво ду имеет вид >>>, но ее можно изменить. Квадратные скобки могут ис пользоваться для доступа к элементам любых типов данных, являю щихся последовательностями, таких как строки и списки. Такая непро тиворечивость синтаксиса – одно из оснований красоты языка Python. Обратите внимание: индексы в языке Python начинаются с 0. В Python тип str и элементарные числовые типы, такие как int, явля ются неизменяемыми, то есть однажды установив значение, его уже нельзя будет изменить. На первый взгляд, такое ограничение кажется «Золотой запас» Python 29 странным, но на практике это не влечет за собой никаких проблем. Единственная причина, по которой об этом было упомянуто здесь, за ключается в том, что имея возможность с помощью квадратных ско бок извлекать отдельные символы, мы не имеем возможности изме нять их. (Обратите внимание: в языке Python под символом понимает ся строка, имеющая длину, равную 1.) Для преобразования элемента данных из одного типа в другой мы мо жем использовать конструкцию datatype(item). Например: >>> int("45") 45 >>> str(912) '912' Преобразование int() терпимо относится к начальным и конечным про белам, поэтому оператор int("45") также будет работать. Преобразова ние str() может применяться практически к любым типам данных. Мы легко можем наделять поддержкой преобразований str(), int() и дру гих преобразований свои собственные типы данных, если в этом име ется какойто смысл; это будет показано в главе 6. Если преобразова ние терпит неудачу, возбуждается исключение – мы коротко затронем тему обработки исключений, когда будем рассматривать составляю щую №5, а полное обсуждение исключений приводится в главе 4. Строки и целые числа подробно будут обсуждаться в главе 2 наряду с другими встроенными типами данных и некоторыми другими типа ми из стандартной библиотеки Python. В этой главе также будут рас сматриваться операции, применимые к неизменяемым последователь ностям, таким как строки. Составляющая №2: ссылки на объекты Теперь, зная о существовании некоторых типов данных, нам необходимо рассмотреть переменные, которые хра нят эти данные. В языке Python нет переменных как таковых – вместо них используются ссылки на объекты. Когда речь заходит о неизменяемых объектах, таких как int или str, между переменной и ссылкой на объект нет никакой разницы. Однако различия начинают прояв ляться, когда дело доходит до изменяемых объектов, но эти различия редко имеют практическое значение. Мы будем использовать термины переменная и ссылка на объект как взаимозаменяемые. Взгляните на следующие крошечные примеры, а затем мы обсудим их подробнее. x = "blue" y = "green" z = x Поверхно стное и глубокое копирование, стр. 173 30 Глава 1. Быстрое введение в процедурное программирование Синтаксис выглядит очень просто: objectReference = value. Нет ника кой необходимости в предварительном объявлении или определении типов значений. Когда интерпретатор Python выполняет первую инст рукцию, он создает объект типа str с текстом "blue", а затем создает ссылку на объект с именем x, которая ссылается на объект типа str. Практически можно сказать, что «переменной x была присвоена стро ка 'blue'». Вторая инструкция похожа на первую. Третья инструкция создает новую ссылку на объект с именем z и записывает в нее ссылку на тот же самый объект, на который указывает ссылка x (в данном слу чае это объект типа str с текстом "blue"). Оператор = – это не оператор присваивания значения переменной, как в некоторых других языках программирования. Оператор = связывает ссылку на объект с объектом, находящимся в памяти. Если ссылка на объект уже существует, ее легко можно связать с другим объектом, указав этот объект справа от оператора =. Если ссылка на объект еще не существует, она будет создана оператором =. Продолжим пример со ссылками x, y и z и выполним перепривязку. Как уже упоминалось ранее, с символа # начинаются комментарии, которые продолжаются до конца строки: print(x, y, z) # выведет: blue green blue z = y print(x, y, z) # выведет: blue green green x = z print(x, y, z) # выведет: green green green После выполнения четвертой инструкции (x = z) все три ссылки на объекты будут ссылаться на один и тот же объект типа str. Поскольку теперь не осталось ни одной ссылки, которая ссылалась бы на строку "blue" , Python сможет утилизировать ее. На рис. 1.2 схематически изображены взаимоотношения между объ ектами и ссылками на объекты. a = 7 a 7 Кружочками изображены ссылки на объекты. Прямоугольниками – объекты в памяти. a = 7 b = a a 7 b a 7 a = 7 b = a a = "Liberty" b "Liberty" Рис. 1.2. Объекты и ссылки на объекты «Золотой запас» Python 31 Имена, используемые для идентификации ссылок на объекты (называются идентификаторами), имеют оп ределенные ограничения. В частности, они не могут сов падать с ключевыми словами языка Python и должны начинаться с алфавитного символа или с символа под черкивания, за которым следует ноль или более алфа витных символов, символов подчеркивания или цифр. Ограничений на длину имен не накладывается, а алфа витные и цифровые символы – это те символы, что опре деляются Юникодом, включая, но не ограничиваясь цифрами и символами ASCII («a», «b», …, «z», «A», «B», …, «Z», «0», «1», …, «9»). Идентификаторы в языке Py thon чувствительны к регистру символов, то есть имена LIMIT , Limit и limit – это три разных имени. Дополни тельные подробности по этому вопросу и ряд необычных примеров приводятся в главе 2. В языке Python используется динамический контроль типов, то есть ссылки на объекты в любой момент могут повторно привязываться к различным объектам (которые могут относиться к данным различ ных типов). В языках со строгим контролем типов (таких как C++ и Java) разрешается выполнять только те операции, которые допусти мы для данных, участвующих в операции. В языке Python также име ется подобное ограничение, но в данном случае это не называется стро гим типизированием, потому что допустимость операции может изме ниться, например, когда ссылка на объект будет повторно связана с объектом другого типа. Например: route = 866 print(route, type(route)) # выведет: 866 route = "North" print(route, type(route)) # выведет: North Здесь была создана новая ссылка на объект с именем route и связана с новым значением 866 типа int. С этого момента мы можем использо вать оператор / применительно к route, потому что деление – это до пустимая операция для целых чисел. После этого мы вновь воспользо вались ссылкой route и связали ее с новым объектом типа str, имею щим значение «North», а объект типа int был утилизирован сборщи ком мусора, так как не осталось ни одной ссылки, которая ссылалась бы на него. С этого момента применение оператора / будет вызывать ошибку TypeError, так как деление не является допустимой операцией для строк. Функция type() возвращает тип данных (который также называется «классом») для указанного элемента. Эта функция может быть очень полезной на этапе тестиро вания и отладки, но в готовом программном коде, как Идентифи каторы и ключевые слова, стр. 68 Функция isin stance() , стр. 284 32 Глава 1. Быстрое введение в процедурное программирование правило, не используется, так как существует более удобная альтерна тива, в чем вы убедитесь в главе 6. При экспериментировании с программным кодом на языке Python в ин терактивной оболочке интерпретатора или в командной оболочке Python – такой, как предоставляется средой IDLE, достаточно просто ввести имя ссылки на объект, чтобы интерпретатор вывел значение связанного с ней объекта. Например: >>> x = "blue" >>> y = "green" >>> z = x >>> x 'blue' >>> x, y, z ('blue', 'green', 'blue') Это намного удобнее, чем постоянно вызывать функцию print(), но эта особенность работает только при использовании интерпретатора Py thon в интерактивном режиме – в любых создаваемых программах и модулях для вывода значений следует использовать функцию print() или подобные ей. Обратите внимание, что в последнем случае Python вывел значения в круглых скобках, разделив их запятыми – так обо значается тип данных tuple (кортеж), то есть упорядоченная, неизме няемая последовательность объектов. О кортежах мы поговорим в сле дующем разделе. Составляющая №3: коллекции данных Часто бывает удобно хранить целую коллекцию элементов данных. В языке Python для этого имеется несколько типов коллекций, способ ных хранить элементы данных, включая ассоциативные массивы и множества. Но в этом разделе мы рассмотрим только два типа кол лекций: tuple (кортежи) и list (списки). Кортежи и списки в языке Py thon могут использоваться для хранения произвольного числа элемен тов данных любых типов. Кортежи относятся к разряду неизменяе мых объектов, поэтому после создания кортеж нельзя изменить. Спи ски относятся к разряду изменяемых объектов, поэтому мы легко можем вставлять и удалять элементы списка по своему желанию. Кортежи создаются с помощью запятых (,), как показано ниже: >>> "Denmark", "Norway", "Sweden" ('Denmark', 'Norway', 'Sweden') >>> "one", ('one',) При выводе кортежа интерпретатор Python заключает его в круглые скобки. Многие программисты имитируют такое поведение и заключают литералы кортежей в круг лые скобки. Если создается кортеж с одним элементом, Создание и вызов функций, стр. 52 «Золотой запас» Python 33 то даже при наличии круглых скобок мы обязаны использовать запя тую, например: (1,). Пустой кортеж создается с помощью пустых круглых скобок (). Запятая также используется для отделения аргу ментов при вызове функции, поэтому, если в качестве аргумента тре буется передать литерал кортежа, мы должны заключать его в круг лые скобки, чтобы избежать неоднозначности. Ниже приводятся несколько примеров списков: [1, 4, 9, 16, 25, 36, 49] ['alpha', 'bravo', 'charlie', 'delta', 'echo'] ['zebra', 49, 879, 'aardvark', 200] [] Как показано здесь, списки могут создаваться с помощью квадратных скобок ([]), но позднее мы познакомимся с другими способами созда ния списков. Четвертый список в примере – это пустой список. Списки и кортежи хранят не сами элементы данных, а ссылки на объ екты. При создании списков и кортежей (а также при добавлении но вых элементов в списки) создаются копии указанных ссылок на объек ты. В случае значенийлитералов, таких как целые числа и строки, в памяти создаются и инициализируются объекты соответствующих типов, затем создаются ссылки, указывающие на эти объекты, и эти ссылки помещаются в список или в кортеж. Как и все остальное в языке Python, коллекции данных – это объекты: благодаря этому имеется возможность вкладывать одни объектыколлекции в другие, напри мер, без лишних формальностей можно создать список списков. В некоторых ситуациях тот факт, что кортежи и списки, а также большинство коллекций других ти пов, хранят ссылки на объекты, а не сами объекты, име ет большое значение – об этом будет рассказываться в главе 3 (начиная со стр. 136). В процедурном программировании мы вызываем функции и часто пе редаем им данные в виде аргументов. Например, мы уже познакоми лись с функцией print(). Другая часто используемая функция в языке Python – это функция len(), которая в качестве аргумента принимает единственный элемент данных и возвращает его «длину» в виде значе ния типа int. Ниже приводятся несколько примеров вызова функции len() – в этом примере мы не стали выделять вывод интерпретатора жирным шрифтом, полагая, что вы уже сами сможете отличить, что вводится с клавиатуры, а что выводится интерпретатором: >>> len(("one",)) 1 >>> len([3, 5, 1, 2, "pause", 5]) 6 >>> len("automatically") 13 Поверхно стное и глубокое копирование, стр. 173 34 Глава 1. Быстрое введение в процедурное программирование Кортежи, списки и строки имеют «размер», то есть это типы данных, которые обладают категорией размера, и элементы данных таких типов могут передаваться функции len(). (Если функции len() передать элемент, тип которого не предполагает такого понятия, как раз мер, будет возбуждено исключение.) Все элементы данных в языке Python являются объектами (называе мых также экземплярами) определенных типов данных (называемых также классами). Мы будем использовать термины тип данных и класс как взаимозаменяемые. Одно из основных отличий между объ ектом и простым элементом данных в некоторых других языках про граммирования (например, встроенные числовые типы в C++ или Java) состоит в том, что объект может обладать методами. В сущности, ме тод – это обычная функция, которая вызывается в контексте конкрет ного объекта. Например, тип list имеет метод append(), с помощью ко торого можно добавить новый объект в список, как показано ниже: >>> x = ["zebra", 49, 879, "aardvark", 200] >>> x.append("more") >>> x ['zebra', 49, 879, 'aardvark', 200, 'more'] Объект x знает, что принадлежит к типу list (все объекты в языке Py thon знают, к какому типу они принадлежат), поэтому нам не требует ся явно указывать тип данных. Первым аргументом методу append() передается сам объект x – делается это интерпретатором Python авто матически, в порядке реализованной в нем поддержки методов. Метод append() изменяет первоначальный список. Это возможно благо даря тому, что списки относятся к категории изменяемых объектов. Потенциально это более эффективно, чем создание нового списка, включающего первоначальные элементы и дополнительный элемент с последующим связыванием ссылки на объект с новым списком, осо бенно для очень длинных списков. В процедурном языке то же самое могло бы быть достигнуто с исполь зованием метода append(), как показано ниже (что является совершен но допустимым вариантом в языке Python): >>> list.append(x, "extra") >>> x ['zebra', 49, 879, 'aardvark', 200, 'more', 'extra'] Здесь указываются тип данных и метод этого типа данных, а в качест ве первого аргумента передается элемент данных того типа, метод ко торого вызывается, за которым следуют дополнительные параметры. (С точки зрения наследования между этими двумя подходами сущест вует малозаметное семантическое отличие; на практике наиболее часто используется первая форма. О наследовании рассказывается в главе 6.) Понятие «размер», стр. 443 «Золотой запас» Python 35 Если вы еще не знакомы с объектноориентированным программиро ванием, на первый взгляд такая форма вызова функций может пока заться немного странной. Пока вам достаточно будет знать, что обыч ные функции в языке Python вызываются так: functionName(argiments), а методы вызываются так: objectName.methodName(arguments). (Об объ ектноориентированном программировании рассказывается в главе 6.) Оператор точки («оператор доступа к атрибуту») используется для дос тупа к атрибутам объектов. До сих пор мы видели только одну разно видность атрибутов – методы, но атрибут может быть объектом любого типа. Поскольку атрибут может быть объектом, имеющим свои атри буты, которые также могут быть объектами, обладающими атрибута ми и т. д., мы можем использовать столько операторов точки, сколько потребуется для доступа к необходимому атрибуту. Тип list имеет множество других методов, включая insert(), который используется для вставки элемента в позицию с определенным индек сом, и remove(), который удаляет элемент с указанным индексом. Как уже упоминалось ранее, счет индексов в языке Python начинается с 0. Ранее мы уже видели, что существует возможность извлечь из строки символ, используя оператор квадратных скобок, и отметили, что этот оператор может использоваться с любыми последовательностями. Спи ски – это последовательности, поэтому мы можем выполнять следую щие операции: >>> x ['zebra', 49, 879, 'aardvark', 200, 'more', 'extra'] >>> x[0] 'zebra' >>> x[4] 200 Кортежи также являются последовательностями, поэтому, если бы ссылка x указывала на кортеж, мы могли бы извлекать элементы с по мощью квадратных скобок точно так же, как это было сделано со ссыл кой x, представляющей список. Но так как списки являются изменяе мыми объектами (в отличие от строк и кортежей, которые являются неизменяемыми объектами), мы можем использовать оператор квад ратных скобок еще и для изменения элементов списка. Например: >>> x[1] = "forty nine" >>> x ['zebra', 'forty nine', 879, 'aardvark', 200, 'more', 'extra'] Если указать индекс, выходящий за пределы списка, будет возбужде но исключение – обработка исключений вкратце будет рассматривать ся в разделе с описанием составляющей №5, а полный охват этой темы дается в главе 4. Мы уже несколько раз использовали термин последовательность, по лагаясь на неформальное понимание его смысла, и продолжим его |