WWW.DISSERS.RU

БЕСПЛАТНАЯ ЭЛЕКТРОННАЯ БИБЛИОТЕКА

   Добро пожаловать!

Pages:     | 1 || 3 | 4 |   ...   | 7 |

«Г. Россум, Ф.Л.Дж. Дрейк, Д.С. Откидач Язык программирования Python Г. Россум, Ф.Л.Дж. Дрейк, Д.С. Откидач, М. Задка, М. Левис, С. Монтаро, Э.С. Реймонд, А.М. Кучлинг, М.-А. Лембург, К.-П. Йи, Д. Ксиллаг, ...»

-- [ Страница 2 ] --

: integer division or modulo 80 Глава 8. Ошибки и исключения 8.4 Генерация исключений Инструкция raise позволяет программисту принудительно сгенерировать исключение.

Например:

>>> raise NameError(’HiThere’) Traceback (innermost last):

File "", line NameError: HiThere В качестве аргумента raise используется экземпляр класса. Класс указывает на тип исключения;

аргумент, передаваемый конструктору, обычно описывает “подробно сти” возникновения исключительной ситуации.

8.5 Исключения, определяемые пользователем Вы можете использовать свои собственные исключения, используя строковые выраже ния для обозначения его имени (устаревший способ) или создавая новые классы исклю чения. Например:

>>> class MyError(Exception): pass...

>>> try:

... raise MyError(2*2)... except MyError, e:

... print ’ MyError, value ’, e...

MyError, value >>> raise MyError(1) Traceback (innermost last):

File "", line main.MyError: Подробную информацию о классах Вы можете получить в главе 9.

8.6 “Страхование” от ошибок Еще один вариант записи инструкции try — с определением “страховочной” ветви finally, которая будет выполняться при любых обстоятельствах. Например:

>>> try:

... raise KeyboardInterrupt() 8.6. “Страхование” от ошибок... finally:

... print ’ !’...

!

Traceback (innermost last):

File "", line KeyboardInterrupt Ветвь finally выполняется независимо от того, возникла ли исключительная ситуация во время выполнения блока try или нет, в том числе и если выход происходит по инструкции break или return.

Инструкция try может иметь либо одну или несколько ветвей except, либо одну ветвь finally, но не оба варианта сразу.

Глава Классы Механизм классов языка Python использует минимум нового синтаксиса и семантики.

++ Он представляет собой смесь механизмов классов C и Modula-3. Так же, как и модули, классы не возводят абсолютного барьера между определением и пользователем, а скорее полагаются на хороший стиль пользователя “не вламываться” в определение. Однако наиболее важные особенности классов полностью сохранены: механизм наследования допускает несколько базовых классов, производный класс может переопределить любые методы базовых классов, из метода можно вызывать метод с тем же именем базового класса. Объекты могут содержать произвольное количество собственных данных.

++ Говоря в терминологии C, все атрибуты класса (включая поля данных) являются открытыми (public), а все методы — виртуальными (virtual). Как и в Modula-3, нет со кращения, позволяющего ссылаться на атрибуты объекта из его метода: функция-метод определяется с явным первым аргументом, представляющим сам объект, и подставляе мым автоматически при вызове. Подобно Smalltalk, классы сами являются объектами, хотя и в более широком смысле этого слова: в языке Python все типы данных явля ются объектами. Это позволяет использовать общую семантику для импортирования и ++ переименования, но встроенные типы (как и в C и Modula-3) нельзя использовать в ++ качестве базовых классов. Кроме того, так же как в C, но в отличие от Modula-3, можно переопределить большинство встроенных операций над экземплярами классов.

9.1 Несколько слов о терминологии По причине отсутствия универсальной терминологии, время от времени мы будем поль ++ зоваться терминами Smalltalk и C. Также следует предупредить, что существует тер минологическая ловушка для читателей, знакомых с объектно-ориентированным про граммированием: слово “объект” в языке Python совсем не обязательно означает экзем пляр класса. Так, объекты встроенных типов, такие как целые числа, списки и даже некоторые экзотические, вроде файлов, тоже не являются экземплярами классов. Одна ко все объекты языка Python имеют общую часть семантики, лучше всего описываемую словом “объект”.

Один и тот же объект может быть привязан к нескольким именам, в том числе находящимся в различных пространствах имен (использование псевдонимов, aliasing).

На это свойство обычно не обращают внимания при первом знакомстве, и его можно благополучно игнорировать, пока Вы работаете с неизменяемыми объектами (числа, строки, кортежи). Однако использование псевдонимов (преднамеренно!) отражается на семантике кода, работающего с изменяемыми объектами (списки, словари, файлы и т.

9.2. Области видимости и пространства имен п.). Обычно из этого извлекают пользу, так как псевдонимы во многих отношениях работают аналогично указателям. Например, передача объекта в качестве аргумента достаточно эффективна, потому что реализована как передача указателя. Если функция изменяет объект, переданный в качестве аргумента, все изменения будут видны после возврата из функции — таким образом, отпадает необходимость в использовании двух различных механизмов передачи аргументов, как это сделано в языке Pascal.

9.2 Области видимости и пространства имен Перед тем, как знакомиться с классами, следует рассказать о правилах языка, касающих ся областей видимости. Определения классов выполняют несколько изящных приемов с пространствами имен, и Вам следует знать о работе областей видимости и пространств имен, для полного понимания происходящего.

Начнем с нескольких определений. Пространство имен определяет отображение имен в объекты. Большинство пространств имен в языке Python реализованы как сло вари, что, однако, никак себя не проявляет (кроме производительности) и может быть изменено в будущем. Вот несколько примеров пространств имен: множество встроенных имен (функции, исключения), глобальные имена в модуле, локальные имена при вызове функций. В этом смысле множество атрибутов объекта также образует пространство имен. Важно понимать, что между именами в разных пространствах имен нет связи.

Например, два модуля могут определить функции с именем “maximize” не создавая при этом путаницы — пользователь должен ссылаться на них с использованием имени модуля в качестве приставки.

Под словом атрибут мы подразумеваем любое имя, следующее после точки: на пример, в выражении z.real, real является атрибутом объекта z. Строго говоря, имена в модулях являются атрибутами модуля: в выражении modname.funcname, modname является объектом-модулем и funcname является его атрибутом. В этом слу чае имеет место прямое соответствие между атрибутами модуля и глобальными имена ми, определенными в модуле: они совместно используют одно пространство имен1!

Атрибуты могут быть доступны только для чтения, а могут и допускать присваи вание. Во втором случае Вы можете записать ‘modname.attribute = 42’ или даже удалить его, используя инструкцию del: ‘del modname.attribute’.

Пространства имен создаются в различные моменты времени и имеют разную про должительность жизни. Пространство имен, содержащее встроенные имена, создает ся при запуске интерпретатора и существует все время его работы. Глобальное про странство имен модуля создается, когда он считывается, и, обычно, также существует до завершения работы интерпретатора. Инструкции, выполняемые на верхнем уровне, т. е. читаемые из файла-сценария или интерактивно, рассматриваются как часть модуля main, имеющего собственное глобальное пространство имен. (В действительности, Есть одно исключение. Объект-модуль имеет секретный атрибут dict, содержащий словарь, используемый для реализации пространства имен модуля. Имя dict является атрибутом, однако не является глобальным именем. Не следует использовать атрибут dict где-либо кроме отладчиков, так как это нарушает абстракцию реализации пространства имен.

84 Глава 9. Классы встроенные имена также находятся в модуле — builtin.) Локальное пространство имен функции создается при вызове функции и удаляет ся при выходе из нее (возвращается значение или генерируется исключение, которое не обрабатывается внутри функции). Безусловно, при рекурсивном вызове создается собственное локальное пространство имен для каждого вызова.

Область видимости — фрагмент программы, в котором пространство имен непо средственно доступно, то есть нет необходимости в использовании записи через точку для того, чтобы поиск имени производился в данном пространстве имен.

Несмотря на статическое определение, области видимости используются динами чески. В любой момент времени выполнения программы используется ровно три вложен ных области видимости (три непосредственно доступных пространства имен). Сначала поиск имени производится во внутренней области видимости, содержащей локальные имена. Далее — в средней, содержащей глобальные имена модуля. И, наконец, во внеш ней, содержащей встроенные имена.

Обычно локальная область видимости соответствует локальному пространству имен текущей функции (класса, метода). За пределами функции (класса, метода), ло кальная область видимости соответствует тому же пространству имен, что и глобальная:

пространству имен текущего модуля.

Важно понимать, что область видимости определяется по тексту: глобальная об ласть видимости функции, определенной в модуле — пространство имен этого модуля, независимо от того, откуда или под каким псевдонимом функция была вызвана. С другой стороны, реально поиск имен происходит динамически, во время выполнения. Однако язык развивается в сторону статического разрешения имен, определяемого во время “компиляции”, поэтому не стоит полагаться на динамическое разрешение имен! (Фак тически, локальные переменные уже определяются статически.) В языке Python есть особенность: присваивание всегда производится имени в локальной области видимости, если перед этим не было указано явно (инструкция global), что переменная находится в глобальной области видимости. Присваивание не копирует данные — оно только привязывает имя к объекту. То же самое верно и для удаления: инструкция ‘del x’ удаляет имя x из пространства имен, соответствующего локальной области видимости. В сущности, все операции, которые вводят новые имена, используют локальную область. Так, импортирование модуля и определение функции привязывают модуль или функцию к локальной области видимости.

9.3 Первый взгляд на классы Классы требуют немного нового синтаксиса, добавляют три новых типа объектов и некоторое которое количество новой семантики.

9.3. Первый взгляд на классы 9.3.1 Синтаксис определения класса Простейшая модель определения класса выглядит следующим образом:

class _:

.

.

.

N Определение класса, подобно определению функции (инструкция class, как и def), должно быть выполнено перед тем, как класс можно будет использовать. (Предполага ется, что Вы можете поместить определение класса в одну из ветвей инструкции if или в тело функции.) На практике инструкции внутри определения класса обычно являются определе ниями функций, но разрешены, и иногда полезны, другие инструкции. Определение функции внутри класса имеет специфическую форму записи списка аргументов, продик тованную соглашениями по вызову методов. Мы вернемся к этим особенностям позже.

Когда выполняется определение класса, создается новое пространство имен и ис пользуется в качестве локальной области видимости при выполнении инструкций в теле определения. Таким образом, все присваивания производятся именам из нового про странства имен. В частности, определение функции создает соответствующее имя в пространстве имен класса.

По окончании выполнения определения функции, создается объект-класс. По су ществу он является “оболочкой” пространства имен, созданного определением класса.

В следующем разделе мы расскажем об объектах-классах более подробно. Исходная область видимости (которая была перед выполнением определения класса) восстанав ливается, и объект-класс привязывается к имени класса (в приведенном примере — _) в пространстве имен, соответствующему исходной области видимости.

9.3.2 Объекты-классы Объекты-классы поддерживают два вида операций: доступ к атрибутам и создание эк земпляра класса.

Доступ к атрибутам объекта-класса осуществляется так же, как и для других объектов языка Python: obj.attrname. Действительными именами атрибутов являют ся все имена, помещенные в пространство имен класса при создании объекта-класса.

Пусть определение класса выглядит следующим образом:

class MyClass:

’ ’ 86 Глава 9. Классы i = def f(x):

return ’ ’ Тогда i и f являются действительными атрибутами, ссылающимися на целое число и объект-метод соответственно. Атрибутам можно присваивать новые значения, например, Вы можете изменить значение MyClass.i. doc также является действительным атрибутом, ссылающимся на строку документации класса: ’ ’.

Создание экземпляра класса использует запись вызова функций. Просто считайте объект-класс функцией без параметров, возвращающей созданный экземпляр класса.

Например, x = MyClass() создает новый экземпляр класса и присваивает его локальной переменной x.

В приведенном примере создается “пустой” объект. Во многих случаях необходимо создавать объект с определенным начальным состоянием — для этого класс должен содержать специальный метод init(), например:

class MyClass:

def init(self):

self.data = [] Если для класса определен метод init(), то он автоматически вызывается при создании каждого экземпляра этого класса.

Для большей гибкости метод init(), конечно, может иметь аргументы. В этом случае, аргументы, используемые при создании экземпляра класса, передаются методу init(). Например:

>>> class Complex:

... def init(self, realpart, imagpart):

... self.r = realpart... self.i = imagpart...

>>> x = Complex(3.0, -4.5) >>> x.r, x.i (3.0, -4.5) 9.3.3 Объекты-экземпляры Что мы теперь можем делать с объектами-экземплярами? Основная операция, воспри нимаемая объектом-экземпляром — доступ к его атрибутам. Атрибуты могут быть двух 9.3. Первый взгляд на классы видов.

Первый — атрибуты данных. Они соответствуют “переменным экземпляра” в ++ Smalltalk и “членам данных” в C. Атрибуты данных не нужно декларировать: они возникают, когда им первый раз присваивают значение. Например, если x является экземпляром класса MyClass, определенного выше, следующий код выведет значение 16:

x.counter = while x.counter < 10:

x.counter = x.counter * print x.counter del x.counter Второй тип атрибутов — методы. Метод — это функция, “принадлежащая” объ екту. В языке Python термин “метод” применим не только к экземплярам классов — другие объекты тоже могут иметь методы. Например, у объектов-списков есть методы append(), insert(), remove(), sort() и т. д. Однако ниже, если явно не указано другого, мы будем использовать термин “метод” для методов экземпляров (instance method).

Действительные имена методов объекта-экземпляра зависят от класса: все атри буты класса, являющиеся объектами-функциями автоматически становятся методами при обращении к соответствующим атрибутам экземпляра2. Так, в нашем примере x.f является методом, привязанным к объекту x. Но x.f — это не то же самое, что и MyClass.f. В первом случае метод “знает” объект, к которому он применяется, во втором — он не привязан к какому-либо объекту и ведет себя аналогично функции.

9.3.4 Методы экземпляров классов Обычно метод вызывают непосредственно:

x.f() В нашем примере он вернет строку ’ ’. Однако совсем не обяза тельно вызывать метод прямо. x.f является объектом-методом, и его можно сохранить для дальнейшего использования:

xf = x.f while 1:

print xf() Функция может быть записана в lambda-форме, однако другие объекты, поддерживающие вызов (класс или экземпляр класса, для которого определен метод call) не подходят.

88 Глава 9. Классы будет выводить ’ ’ до тех пор, пока выполнение не будет прервано.

Что же происходит при вызове метода? Вы могли заметить, что x.f() вызывается без аргумента, несмотря на то, что в определении аргумент указан. Что же случилось с аргументом? Конечно, Python генерирует исключение, если функцию, требующую аргу мент, вызвать без него — даже если аргумент на самом деле не используется.

Вы могли уже догадаться: особенность методов состоит в том, что объект, для которого он применяется, передается в качестве первого аргумента. В нашем примере вызов x.f() полностью эквивалентен MyClass.f(x). В общем, вызов метода, привя занного к объекту, со списком из n аргументов полностью эквивалентен вызову соответ ствующего не привязанного метода (или функции) со списком аргументов, полученным добавлением объекта перед первым аргументом.

Если Вы все еще не поняли, как работают методы, возможно, взгляд на реализа цию внесет ясность. Если Вы ссылаетесь на атрибут объекта, не являющийся атрибутом данных, то поиск атрибута производится в классе, экземпляром которого является объ ект. Если имя соответствует действительному атрибуту класса, который определен как функция, то атрибут считается методом. Метод является структурой, содержащей ин формацию о классе, в котором он определен, и функции, его представляющей, но “не знает”, к какому именно объекту будет применяться (не привязанный к объекту метод).

Соответствующий атрибут экземпляра класса, в свою очередь, содержит, помимо ука занной информации, еще и ссылку на объект-экземпляр (привязанный к объекту метод) упакованные вместе в объекте-методе. При вызове метода со списком аргументов, он распаковывается, создается новый список аргументов из объекта-экземпляра и исходно го списка аргументов, и с этим списком вызывается объект-функция.

9.4 Выборочные замечания Атрибуты экземпляров (обычно атрибуты данных) записываются поверх атрибутов клас сов (обычно методов) с тем же именем. Чтобы избежать конфликтов имен, которые могут привести к тяжело обнаружимым ошибкам, полезно использовать своего рода со глашение, позволяющее минимизировать вероятность конфликтов. Например: называть методы именами, начинающимися с заглавной буквы, добавлять небольшую приставку в начало имен атрибутов данных (возможно просто символ подчеркивания) или исполь зовать глаголы для методов и существительные для атрибутов данных.

В некоторых случаях изменение атрибутов данных напрямую, а не с помощью специально предназначенных для этого методов, может привести к порче инварианта объекта и непригодности его для дальнейшего использования. Вы можете “спрятать” данные и, тем самым, защитить их от случайного изменения. Для этого в языке су ществует соглашение: все атрибуты, имена которых содержат не менее двух символов подчеркивания в начале и не более одного символа подчеркивания в конце, считаются частными и доступны только из методов объекта. (На самом деле, Вы можете получить доступ к частным атрибутам извне, используя специальное имя, однако такой доступ ни как не назовешь случайным. Более подробно работа с частными атрибутами описана в разделе 9.6.) С другой стороны, модули расширения, написанные на C, могут полностью 9.4. Выборочные замечания спрятать детали реализации и при необходимости полностью контролировать доступ.

Обычно первый аргумент в определении метода называют self. Это не более чем соглашение: имя self не имеет абсолютно никакого специального значения. Однако, следуя этому соглашению, Вы делаете код более понятным для других программистов.

(Некоторые программы, например программы просмотра классов, рассчитаны на то, что пользователь всегда следует этому соглашению.) Любой объект-функция, являющийся атрибутом класса, определяет метод экзем пляров этого класса. Совсем не обязательно, чтобы определение функции находилось в определении класса: присваивание объекта-функции локальной переменной также будет работать. Например:

# def f1(self, x, y):

return min(x, x+y) class C:

f = f def g(self):

return ’ ’ h = g Теперь f, g и h являются атрибутами класса C и ссылаются на объекты функции и, следовательно, все они будут методами экземпляров класса C. Вы можете также ис пользовать функцию, определенную с помощью оператора lambda. Заметим, что такая практика обычно только сбивает с толку.

Методы могут вызывать другие методы, как атрибуты аргумента self, например:

class Bag:

def init(self):

self.data = [] def add(self, x):

self.data.append(x) def addtwice(self, x):

self.add(x) self.add(x) Методы могут ссылаться на глобальные имена точно таким же способом, как и обычные функции. Глобальная область видимости, ассоциированная с методом — это глобальное пространство имен модуля, содержащего определение функции (так как опре деление функции обычно находится в определении класса, то — в глобальном простран стве имен модуля, содержащего определение класса). В то время как редко существует веская причина использовать глобальные данные в методе, глобальная область видимо сти все же находит множество разумных применений: использование импортированных в глобальную область видимости модулей, а также определенных в ней функций и клас сов.

90 Глава 9. Классы Атрибуты классов ведут себя как статические атрибуты их экземпляров (то есть общие для всех экземпляров данного класса). Однако присвоить такому атрибуту новое значение Вы можете, только обратившись к нему как атрибуту того класса, в котором он определен (в противном случае Вы лишь создадите новый атрибут экземпляра с таким же именем).

9.5 Наследование Конечно, особенность языка не достойна называться “классом” без поддержки насле дования. Определение производного класса с именем _ выглядит следующим образом:

class _(_):

.

.

.

N Базовый класс (_) должен быть определен в области видимости, в кото рой находится определение производного класса (_). Вместо имени базового класса можно использовать выражение, например, если базовый класс опреде лен в другом модуле:

class _(._):

Определение производного класса выполняется так же, как и определение базо вого класса. Сконструированный объект-класс помнит базовый — он используется для разрешения имен атрибутов: если запрошенный атрибут не найден в классе, поиск про должается в базовом классе. Это правило применяется рекурсивно, если базовый класс, в свою очередь, является производным от другого класса. В создании экземпляра про изводного класса нет ничего особенного: _() порождает новый экземпляр класса.

Производные классы могут переопределить методы базовых классов. Метод базо вого класса, вызывающего другой определенный для него метод, может, на самом деле, вызывать метод производного класса, переопределившего этот метод (говоря в терминах ++ C, все методы в языке Python являются виртуальными).

Переопределяя метод в производном классе, Вы можете также захотеть вызвать метод базового класса с тем же именем. Это можно сделать напрямую: просто вызови те ‘_.(self, _)’, где _ — ссылка на базовый класс в том виде, в котором он доступен в текущей области видимо сти.

В языке Python есть ограниченная поддержка множественного наследования. Опре деления класса с несколькими базовыми классами выглядит следующим образом:

9.6. Частные атрибуты class _(_1, _2, _3):

.

.

.

N Единственное правило, необходимое для объяснения семантики, — правило раз решения имен атрибутов. Поиск производится сначала в глубину, затем слева направо.

Таким образом, если атрибут не найден в _, то он ищется сначала в _1, затем (рекурсивно) в базовых классах класса _ и только потом в _2 и т. д. (Для некоторых людей кажется более есте ственным другой порядок разрешения имен атрибутов — сначала в классах _1, _2, _3 и только потом в базовых классах класса _1. Однако в этом случае возникает зависимость результата от реализации каждого из базовых классов. С принятым же правилом, нет разницы между прямыми и унаследованными атрибутами базовых классов.) 9.6 Частные атрибуты Python предоставляет ограниченную поддержку частных атрибутов классов. Любой атри бут вида (имя которого содержит не менее двух символов подчеркивания в начале и не более одного в конце) заменяется на _, где — имя текущего класса с “обрезанными” символами подчеркивания в начале. Такая обра ботка производится независимо от синтаксического расположения идентификатора, то есть может использоваться для определения частных атрибутов, доступ к которым будет возможен только из методов этого класса и методов его экземпляров. (Имя может быть обрезано, если его длина превысит 255 символов.) Если Вы ссылаетесь на имя, находясь за пределами класса, или если имя класса состоит только из символов подчеркивания, то оно преобразованию не подлежит.

Преобразование имен обеспечивает классам возможность определить “частные” атрибуты, не беспокоясь о том, что производные классы могут переопределить их, а также не дают к ним доступа коду, находящемуся за пределами класса. Заметьте, что правила преобразования разработаны в основном для того, чтобы избежать случайного вмешательства. Иногда доступ к частным атрибутам необходим, например, для отладчи ков — это одна из причин, почему оставлена лазейка.

Если Вы из класса вызываете код с помощью exec, execfile, eval() или evalfile(), то внутри этого кода класс не будет считаться текущим: ситуация ана логична использованию инструкции global — действие ограничивается единовремен но байт-компилированным кодом. Это ограничение распространяется и на getattr(), setattr() и delattr(), а также на прямое использование dict.

92 Глава 9. Классы 9.7 Примеры использования классов Иногда полезно иметь тип данных (record в Pascal или struct в C), объединяющий несколько именованных единиц данных. С этой задачей прекрасно справится пустой класс:

class Employee:

pass # john = Employee() # :

john.name = ’John Doe’ john.dept = ’computer lab’ john.salary = Использование экземпляров классов в качестве исключений позволяет располо жить их в виде “дерева” и обрабатывать ошибки находящиеся на определенной ветви.

Часто вместо ожидаемого типа данных в функции (методе) можно использовать экземпляр класса, эмулирующего методы этого типа. Например, если есть функция, считывающая данные из файла, Вы можете определить класс с методами read() и readline(), которые будут брать данные из буфера вместо файла, и передать его экземпляр функции в качестве аргумента. Используя же специальные методы (см. раз дел 11.6.3), можно эмулировать поведение чисел, списков, словарей и даже полностью контролировать доступ к атрибутам.

В библиотеке стандартных модулей Вы найдете множество примеров классов, эму лирующих поведение строк, списков, словарей, файлов. Рекомендуем посмотреть на ре ализацию таких модулей, как UserString, UserList и UserDict, StringIO. Кроме того, в дистрибутив обычно входит несколько демонстрационных модулей, среди ко торых Вы найдете много интересных примеров, показывающих, как, например, можно реализовать рациональные числа.

9.7.1 Экземпляры классов в качестве исключений Исключения в языке Python могут быть строками (для совместимости со старыми верси ями;

поддержка строк в качестве исключений может быть удалена в будущих версиях) или экземплярами классов. Использование механизма наследования позволяет создавать легко расширяемые иерархии исключений.

Чаще всего инструкция raise употребляется в следующем виде:

raise _ 9.7. Примеры использования классов После ключевого слова except могут быть перечислены как строковые объекты, так и классы. Указанный класс считается “совместимым” с исключением, если исключение является экземпляром этого класса или класса, производного от него (но не наоборот — если в ветви except указан производный класс от того, экземпляром которого является исключение, то исключение не обрабатывается). Следующий пример выведет (именно в этом порядке) ‘B’, ‘C’, ‘D’:

class B:

pass class C(B):

pass class D(C):

pass for c in [B, C, D]:

try:

raise c() except D:

print "D" except C:

print "C" except B:

print "B" Обратите внимание, что если расположить ветви except в обратном порядке, то Вы получите ‘B’, ‘B’, ‘B’ — срабатывает первая ветвь except, совместимая с исключением.

Если исключение-экземпляр не обрабатывается, выводится сообщение об ошибке:

имя класса, двоеточие, пробел и строка, полученная применением встроенной функции str() к исключению-экземпляру.

>>> class MyError:

... def init(self, value):

... self.value = value... def str(self):

... return ‘self.value‘...

>>> raise MyError(1) Traceback (innermost last):

File "", line main.MyError: Язык имеет встроенный набор исключений, которые описаны в разделе 13. В каче стве базового для всех исключений рекомендуется использовать класс Exception — это позволит полностью или частично избежать определения методов, необходимых для инициализации (метод init()) и вывода сообщения об ошибке (метод str(). В большинстве случаев определение нового исключения будет выглядеть совсем просто:

94 Глава 9. Классы >>> class MyError(Exception): pass...

>>> raise MyError(’Oops!’) Traceback (most recent call last):

File "", line 1, in ?

main.MyError: Oops!

9.7.2 Классы-помощники Часто бывает полезно определить класс, помогающий выполнять какие-либо рутинные операции. Например, Вам часто необходимо перебирать параллельно элементы несколь ких последовательностей, а поведение функции map() (см. раздел 5.2) Вас не устраива ет или Вы работаете с длинными последовательностями и не хотите реально создавать последовательность пар (троек, и т. д.). Тогда Вы можете определить простой класс, создающий псевдопоследовательность:

class parallel:

def init(self, *args):

self.args = args def getitem(self, item):

return map(lambda s, i=item: s[i], self.args) С таким классом-помощником задача параллельного перебора элементов сильно упрощается:

>>> seq1 = xrange(10) >>> seq2 = [1, 2, 3, 5, 7] >>> for x, y in parallel(seq1, seq2):

... print x, y...

0 1 2 3 4 Как же наша псевдопоследовательность “узнает” о том, что элементы в одной из последовательностей закончились? Дело в том, что индикатором конца последователь ности при использовании цикла for или средств функционального программирования в языке Python служит исключение IndexError. Исключение генерируется при первом использовании индекса, выходящего за пределы любой из последовательностей (в нашем примере seq1 и seq2). Так что нам достаточно не обрабатывать его и инструкция for будет считать, что закончилась наша псевдопоследовательность.

9.7. Примеры использования классов В версии 2.0 языка появилась новая встроенная функции zip(), предназначенная специально для параллельного перебора нескольких последовательностей. Ее поведение аналогично приведенному здесь классу parallel, с одним лишь отличием — функция zip() создает полноценный список, в который можно вносить изменения.

9.7.3 Множества По своей природе, множества находятся скорее ближе к словарям, чем к спискам. Так же, как и словари обеспечивают уникальность ключей, множества гарантируют уни кальность входящих в него элементов. С другой стороны, списки обеспечивают порядок следования элементов, что для множеств совсем необязательно. Таким образом, встро енный тип dictionary может служить хорошей базой для реализации множеств. Ниже приведено примерное определение класса, реализующего множество.

class set:

def init(self, seq = ()):

# ’_data’, #.

# (’data’), # # set.

if isinstance(seq, set):

# seq set #, # "" self._data = seq._data.copy() else:

# seq # self._data = {} for item in seq:

self._data[item] = None def items(self):

# # :

# for item in myset.items():

#...

return self._data.keys() def tuple_key(self):

# # #. #.

96 Глава 9. Классы items = self._data.keys() #,, # #.

items.sort() return tuple(items) def add(self, item):

# # #.

self._data[item] = None def remove(self, item):

if self._data.has_key(item):

del self._data[item] else:

# raise ValueError("item doesn’t exist") def copy(self):

return set(self) def repr(self):

return ’set(’+‘self.items()‘+’)’ def len(self):

#, # len(). #.

return len(self._data) def contains(self, item):

# ’in’ ’not in’.

return self._data.has_key(item) def cmp(self, other):

#.

return cmp(self._data, other._data) def or(self, other):

# ’|’ ().

res = set(self) res._data.update(other._data) return res def ior(self, other):

# ’|=’.

9.7. Примеры использования классов self._data.update(other._data) return self def and(self, other):

# ’&’ ().

#, #.

if len(other._data) < len(self._data):

self, other = other, self res = set() for item in self._data.keys():

if other._data.has_key(item):

res._data[item] = None return res def iand(self, other):

# ’&=’.

for item in self._data.keys():

if not other._data.has_key(item):

del self._data[item] return self def sub(self, other):

# ’-’ (, # ).

res = set() for item in self._data.keys():

if not other._data.has_key(item):

res._data[item] = None return res def isub(self, other):

# ’-=’.

for item in other._data.keys():

if self._data.has_key(item):

del self._data[item] return self #, # # ().

add = or iadd = ior def xor(self, other):

# ’^’ (, # ).

98 Глава 9. Классы if len(other._data) < len(self._data):

self, other = other, self res = set(other) for item in self._data.keys():

if res._data.has_key(item):

del res._data[item] else:

res._data[item] = None return res def ixor(self, other):

# ’^=’ for item in other._data.keys():

if self._data.has_key(item):

del self._data[item] else:

self._data[item] = None return self 9.7.4 Контроль доступа к атрибутам С помощью специальных методов getattr(), setattr() и delattr() Вы можете контролировать все обращения к атрибутам экзем пляра. Приведем пример класса, реализующего собственные методы getattr() и setattr() и сохраняющего все атрибуты в частной переменной:

class VirtualAttributes:

vdict = None # # vdict:

vdict_name = locals().keys()[0] def init(self):

# ’self.vdict = {}’, #.. # setattr self.dict[self.vdict_name] = {} def getattr(self, name):

return self.vdict[name] def setattr(self, name, value):

self.vdict[name] = value Часть II Встроенные возможности языка Эта часть книги является справочным руководством, описывающим встроенные возможности языка Python. Здесь описаны синтаксис и семантика различных конструк ций языка (выражений, инструкций), встроенные типы данных — в общем то, что обыч но рассматривается как “ядро” языка.

Здесь также описаны встроенные функции и исключения — объекты, использо вание которых не требует предварительного импортирования. Их имена содержатся в отдельном пространстве имен, поиск в котором происходит в последнюю очередь. Таким образом, пользователь может переопределять их в локальном или глобальном простран стве имен.

Глава Синтаксис и семантика В настоящей главе описаны синтаксис и семантика различных конструкций языка Python. Формальное определение грамматики приведено в приложении B.

10.1 Структура строк программы 10.1.1 Логические и физические строки Программа на языке Python состоит из логических строк. Инструкции не могут быть разделены на несколько логических строк, за исключением составных инструкций. Ло гическая строка составляется из одной или нескольких физических строк, следуя пра вилам явного или подразумеваемого объединения строк. Отступ в физической строке, являющейся продолжением логической строки, не имеет значения.

Физическая строка заканчивается символом конца строки, принятым для данной платформы: ASCII символ LF для UNIX, последовательность CR LF для DOS и Windows, CR для Macintosh.

Комментарий начинается символом ‘#’, не являющимся частью строкового литера ла, и заканчивается в конце физической строки. Комментарии лексическим анализато ром игнорируются.

Две или более физических строки могут быть объединены в логическую строку явно с помощью символа обратной косой черты (‘\’): если физическая строка заканчива ется символом обратной косой черты, который не является частью строкового литерала или комментария, она объединяется со следующей физической строкой, образуя одну логическую строку. Например:

if 1900 < year < 2100 and 1 <= month <= 12 \ and 1 <= day <= 31 and 0 <= hour < 24 \ and 0 <= minute < 60 and 0 <= second < 60:

# return Строка, заканчивающаяся символом обратной косой черты, не может содержать комментария. Лексемы не могут быть разделены на несколько строк, за исключением 10.1. Структура строк программы строковых литералов. Использование символа обратной косой черты в любом другом месте, кроме как в конце строки, в строковом литерале и в комментарии, не допускается.

Выражения в обратных кавычках и скобках (круглых, квадратных, фигурных) могут быть разделены на несколько физических строк без использования символа обратной косой черты, например:

month_names = [’’, ’’, # ’’, ’’, # ’’, ’’, # ’’, ’’, ’’, ’’, ’’, ’’] Такие физические строки, объединяемые в одну логическую строку по правилам под разумеваемого объединения, могут содержать комментарии. Строковые литералы, за писанные с использованием трех кавычек, также могут быть разделены на несколько физических строк, которые, однако, не могут содержать комментарии.

Логические строки, содержащие только символы пропуска (whitespace) и, возмож но, комментарий, игнорируются. В интерактивном режиме пустая строка (без символов пропуска и комментариев) используется для обозначения конца составной инструкции.

10.1.2 Отступы Символы пробела и табуляции в начале логических строк используются для опреде ления уровня отступа строки. Уровень отступа строк используется для объединения инструкций в группы.

Сначала каждый символ табуляции (слева направо) заменяется на от одного до восьми пробелов таким образом, чтобы общее количество символов до этого места, включая замененные символы, было кратным восьми. Затем общее количество пробелов в начале логической строки используется для определения уровня отступа. Отступ не может быть разделен на несколько физических строк: для определения уровня отсту па будут использованы символы пропуска до первого символа обратной косой черты.

Только логические строки, имеющие одинаковое количество пробелов (после преобразо вания символов табуляции) в начале строки, считаются имеющими одинаковый уровень отступа.

Приведенный ниже пример имеет правильные, хотя и сбивающие с толку, отступы:

def perm(l):

# l if len(l) <= 1:

return [l] r = [] for i in range(len(l)):

104 Глава 10. Синтаксис и семантика s = l[:i] + l[i+1:] p = perm(s) for x in p:

r.append(l[i:i+1] + x) return r А следующий пример показывает возможные ошибки в отступах:

# : def perm(l):

# :

for i in range(len(l)):

s = l[:i] + l[i+1:] # :

p = perm(l[:i] + l[i+1:]) for x in p:

r.append(l[i:i+1] + x) # : # return r Общепринято добавлять четыре пробела для каждого следующего уровня отступа.

Использование символов табуляции не желательно, так как их интерпретация зависит от используемого редактора и его настроек. Большинство редакторов позволяют на строить автоматическую поддержку отступов. Если Вы работаете с редактором vim, достаточно добавить строчку ‘autocmd FileType python set softtabstop= shiftwidth=4 expandtab autoindent’ в конфигурационный файл редактора ‘.vimrc’ (‘_vimrc’ под Windows).

Символ подачи страницы (FF) может присутствовать в начале строки и игнориру ется при определении отступа. В других местах отступа символ подачи страницы может давать неопределенный эффект (например, обнулить счетчик пробелов).

За исключением начала логической строки и строковых литералов, символы про бела, табуляции и подачи страницы могут быть взаимозаменяемо использованы для разделения лексем.

10.2 Выражения Выражения состоят из атомов (“неделимых” частей), объединенных различными опе раторами. Описание операторов разделено на несколько подразделов, расположенных в порядке убывания приоритета описанных в них операторов (в конце этого раздела приве дена сводная таблица приоритетов). Перед применением бинарных операторов операнды приводятся к общему типу по правилам, описанным в разделе 11.6.3. Назначение боль шинства операторов зависит от типа операндов и описано в соответствующих разделах главы 11.

10.2. Выражения 10.2.1 Атомы Идентификаторы Идентификаторы являются ссылками на локальные, глобальные или встроенные имена.

Если к идентификатору привязан объект в текущем блоке кода и в этом блоке не было явно указано с помощью инструкции global, что имя является глобальным, то иденти фикатор ссылается на локальное имя для этого блока. Если идентификатору в текущем блоке кода не был привязан объект, идентификатор ссылается на глобальное (если оно существует) или встроенное имя. Если же идентификатор явно указан в инструкции global в текущем блоке кода, то он всегда ссылается на глобальное имя.

Если к идентификатору привязан объект, его вычисление как атома в выражении дает этот объект. При попытке использования в выражении имени, не привязанного к объекту, будет сгенерировано исключение NameError.

Идентификаторы (имена) должны начинаться с буквы латинского алфавита или символа подчеркивания и содержать только буквы латинского алфавита, цифры и сим волы подчеркивания. Интерпретатор языка Python различает регистры букв: иденти фикаторы, например, spam и Spam считаются разными. Длина идентификаторов не ограничена.

Следующие идентификаторы являются зарезервированными (или ключевыми) сло вами языка и не могут быть использованы как обычные имена:

and del for is raise assert elif from lambda return break else global not try class except if or while continue exec import pass def finally in print Помимо ключевых слов, некоторые идентификаторы имеют специальное значение (символ ‘*’ обозначает “любое количество любых допустимых символов”;

имена отно сятся к следующему классу, только если они не относятся к предыдущему):

* Системные имена (особых модулей, специальных атрибутов и методов).

* (только в определении класса) Если идентификатор такого вида встречается в определении класса, то он счи тается частным атрибутом класса и подвергается специальному преобразованию.

Например, имя ‘spam’, определенное в классе с именем ‘Ham’, преобразуется к ‘_Ham_spam’. Преобразование производится независимо от контекста, в кото ром идентификатор используется. Если имя класса состоит только из символов подчеркивания, преобразование не производится.

106 Глава 10. Синтаксис и семантика _* Частные объекты модуля, не импортируются инструкцией ‘from module import *’. В интерактивном режиме идентификатор с именем ‘_’ используется для хранения результата вычисления последней инструкции-выражения, сохраня ется в пространстве встроенных имен. Не в интерактивном режиме имя ‘_’ не имеет специального значения (часто используется для выбора сообщений в соот ветствии с текущими национальными установками).

Литеральные выражения Литеральные выражения являются записью значений некоторых встроенных типов: чи сел различного типа (см. раздел 11.1), обычных строк (раздел 11.2.1) и строк Unicode (раздел 11.2.2).

“Замкнутые” выражения Формы, заключенные в обратные кавычки и различные скобки также распознаются синтаксическим анализатором как атомы.

Круглые скобки представляют содержащееся в нем выражение и используются для контроля порядка вычисления. Обратите внимание, что кортеж (см. раздел 11.2.3) обра зуется не с помощью круглых скобок, а путем перечисления выражений через запятую.

Скобки необходимы только для образования пустого кортежа, а также в тех случаях, когда перечисление через запятую используется синтаксисом для других целей (список аргументов функции или инструкции).

Квадратные и фигурные скобки используются для представления списков и слова рей соответственно (см. разделы 11.2.6 и 11.3).

Обратные кавычки используются для получения строкового представления объ екта, являющегося результатом вычисления заключенного в них выражения. Тот же результат Вы можете получить, используя встроенную функцию repr(). Смотрите так же описание функции repr() (раздел 12) и специального метода repr() (раздел 11.6.3).

10.2.2 Первичные выражения Первичное выражение может быть атомом или выражением, представляющим примене ние к первичному выражению (primary) следующих операций, имеющих наибольший приоритет:

primary.attr Операция получения атрибута. Первичное выражение primary должно представ 10.2. Выражения лять объект, поддерживающий доступ к атрибутам. Если атрибут attr объекта primary не доступен, генерируется исключение AttributeError.

primary[key] Операция получения элемента по индексу/ключу, характерная для последователь ностей и отображений (см. разделы 11.2 и 11.3).

primary[slice_list] Операция получения подпоследовательности по срезу. Последовательности встро енного типа поддерживают лишь простую запись среза (slice_list) в виде ‘[start]:[stop]’ (где start — нижняя и stop — верхняя границы). Расши ренная запись (используется, например, в модулях расширения Numerical Python) позволяет указать через запятую несколько срезов вида ‘[start]:[stop][:[step]]’ (step — шаг) или использовать троеточие (‘...’). Например: ‘x[1:10:2]’, ‘x[:10,...]’, ‘x[5:, ::2]’. Расширенная запись среза представляется с по мощью специальных объектов slice и ellipsis, описанных в разделе 11.8.3.

primary(arg_list) Операция вызова. Встроенные типы, поддерживающие вызов, перечислены в раз деле 11.4. arg_list — список (через запятую) аргументов, которые могут быть переданы следующими способами (Вы можете использовать сразу несколько спо собов, однако порядок их следования в списке аргументов должен быть таким, в котором они здесь перечислены (exprN — произвольные выражения):

expr1 [,...] Простой способ передачи позиционных аргументов. Благодаря автоматической упаковке/распаковке кортежей, Вы можете использовать (только при таком способе передачи аргументов) подсписки аргументов:

>>> def print_vector(s, (x, y, z)):

>>> print s+’:’ >>> print ’x =’, x >>> print ’y =’, y >>> print ’z =’, z...

>>> velocity = 0.0, 1.0, 1. >>> print_vector(’ ’, velocity) :

x = 0. y = 1. z = 1. name1 = expr1 [,...] Передача именованных аргументов. nameN — идентификаторы (имена) аргу ментов, exprN — их значения. Порядок следования именованных аргументов не имеет значения.

*seq Передача списка (seq) позиционных аргументов. Позиционные аргументы, переданные обычным способом, дополняются элементами последовательности (любого типа) seq. Такой способ передачи позиционных аргументов доступен, начиная с версии 1.6.

108 Глава 10. Синтаксис и семантика **dict Передача словаря (dict) именованных аргументов. Именованные аргумен ты, переданные обычным способом, дополняются записями из словаря dict.

Такой способ передачи именованных аргументов доступен, начиная с версии 1.6.

Операция вызова всегда возвращает значение (возможно None), если выполнение не было прервано (например, сгенерировано исключение).

10.2.3 Арифметические и битовые операторы Ниже приведены все арифметические и битовые операторы в порядке уменьшения их приоритета. Операторы с одинаковым приоритетом объединены в группы.

x ** y Оператор возведения в степень имеет больший приоритет, чем унарный арифме тический или битовый оператор слева, но меньший, чем унарный арифметический или битовый оператор справа (во избежание нелепых ошибок использование опе ратора not справа от любого арифметического или битового оператора не допус кается). Так, например, выражение ‘-x ** -y’ будет вычисляться справа налево, то есть эквивалентно выражению ‘-(x ** (-y))’.

+x, -x, ~x x * y, x / y, x%y x + y, x - y x << y, x >> y x & y x ^ y x | y 10.2.4 Условные операторы Все условные операторы (операторы сравнения, проверки идентичности и вхожде ния) имеют одинаковый приоритет (больший, чем у логических операторов). Кро ме того, условные операторы могут быть записаны в цепь, например, выражение ‘x < y <= z’ интерпретируется так же, как это принято в математике, и эквива лентно ‘x < y and y <= z’, за исключением того, что y вычисляется только один раз (но в обоих случаях z не вычисляется, если выражение ‘x < y’ ложно).

Заметим, что конструкции типа ‘a < b > c’ вполне допустимы, однако выглядят довольно неприятно (сравнение между a и c не производится). Операторы != и <> полностью эквивалентны, использование первого предпочтительнее.

10.2. Выражения Сравнение x < y 1, если x меньше y, иначе 0.

x <= y 1, если x меньше или равен y, иначе 0.

x > y 1, если x больше y, иначе 0.

x >= y 1, если x больше или равен y, иначе 0.

x == y 1, если x равен y, иначе 0.

x <> y x != y 0, если x равен y, иначе 1. <> и != — две альтернативные формы записи одного оператора, вторая форма предпочтительнее.

Операторы сравнения работают со всеми типами данных. Вы можете сравнивать объекты разного типа. Переменные численных типов равны, если равны их значения.

Если Вы сравниваете обычную строку и строку Unicode, к обычной строке сначала применяется встроенная функция unicode() (считается, что строка имеет кодиров ку ASCII, если обычная строка содержит символы с кодом больше 127, генерируется исключение UnicodeError). Для экземпляров классов может быть определен специ альный метод cmp() (иногда также будет полезен метод rcmp(), см. раздел 11.6.3), который будет использоваться для реализации операторов <, <=, >, >=, ==, != (<>), в том числе, и с объектами других типов (следует помнить, что перед выполнением операций сравнения производится попытка привести операнды к общему типу). Во всех остальных случаях производится проверка идентичности: объекты равны, только если они являются одним и тем же объектом. Порядок следования при сортировке объек тов, для которых не определена операция сравнения, определяется типом объектов и их идентификаторами1.

Идентичность Операторы is и is not проверяют идентичность объектов: являются ли операнды на самом деле одним и тем же объектом (сравниваются идентификаторы объектов;

см.

также описание функции id() в разделе 12).

x is y 1, если x и y ссылаются на один и тот же объект, иначе 0.

Возможны ситуации, при которых obj1 < obj2 и obj2 < obj3, но obj1 > obj3, например, если один из объектов является экземпляром, для которого не определен метод cmp().

110 Глава 10. Синтаксис и семантика x is not y 0, если x и y ссылаются на один и тот же объект, иначе 1.

Вхождение Еще два условных оператора — in и not in — предназначены для определения, является ли объект элементом последовательности (или любого другого контейнера) и подробно описаны в разделе 11.2.

x in y 1, если y содержит элемент, который при сравнении (оператор ==) оказывается равным x, иначе 0.

x not in y 1, если y не содержит элемента равного x, иначе 0.

10.2.5 Истинность Для любого объекта можно проверить его истинность при использовании в инструк циях if и while или в качестве операнда логических операторов, описанных ниже.

Следующие значения считаются ложью:

• None;

• ноль любого числового типа, например, 0, 0L, 0.0, 0j;

• пустая последовательность, например, ’’, (), [];

• пустое отображение (словарь) — {};

• экземпляр класса, для которого определен метод nonzero() или len(), если он возвращает ноль. Дополнительную информацию об этих спе циальных методах Вы можете получить в разделе 11.6.3.

Все остальные значения считаются истинными — так что многие объекты всегда истин ны.

10.2.6 Логические операторы Ниже приведены логические операторы в порядке уменьшения приоритета. Заметим, что оператор not имеет меньший приоритет, чем арифметические и условные операторы. То есть ‘not a == b’ интерпретируется как ‘not (a == b)’, а выражение ‘a == not b’ является синтаксической ошибкой.

10.2. Выражения Операторы or и and всегда возвращают один из своих операндов. Причем второй операнд операторов or и and вычисляется, только если это необходимо для получения результата.

not x Если x ложно, то 1, иначе 0.

x and y Если x ложно, то x, иначе y.

x or y Если x ложно, то y, иначе x.

10.2.7 Оператор lambda lambda param_list: expression Короткая форма создания (безымянной) функции, возвращающей значение выра жения expression. Ее поведение аналогично поведению функции, созданной с помощью инструкции ‘def name(param_list): return expression’. Син таксис списка параметров описан в разделе 10.4.5.

Обратите внимание, что функция, создаваемая с помощью оператора lambda, не может содержать инструкций. Кроме того, lambda-функция (как и функция, опреде ленная с помощью инструкции def) не имеет доступа к локальному пространству имен блока, в котором она определена. Однако Вы можете обойти это ограничение, используя аргументы, имеющие значения по умолчанию, например:

def make_incrementor(increment):

return lambda x, n=increment: x+n lambda имеет наименьший приоритет среди операторов, однако его приоритет больше чем у конструкции, образующей список выражений. Так, например, выражение ‘lambda: 1, 2’ эквивалентно выражению ‘(lambda: 1), 2’ и образует кортеж из двух элементов: функции, возвращающей 1, и числа 2.

10.2.8 Списки выражений Список выражений (аргументов) образуется путем перечисления выражений (идентифи каторов) через запятую. Списки аргументов функции и выражений, образующий кортеж, может содержать завершающую запятую, однако она не имеет никакого значения, за ис ключением одного случая: завершающая запятая необходима для образования кортежа, содержащего один элемент (см. раздел 11.2.3). Использование завершающей запятой в списке аргументов инструкций, кроме инструкции print, не допускается. Завершаю щая запятая в списке аргументов инструкции print указывает на то, что не нужно выводить символ перехода на новую строку (см. раздел 10.3.5).

112 Глава 10. Синтаксис и семантика 10.2.9 Сводная таблица приоритетов Ниже перечислены все конструкции и операторы, которые могут быть использованы для создания выражений, в порядке уменьшения приоритета. Конструкции, перечисленные в одном пункте, имеют одинаковый приоритет.

1. Атомы: идентификаторы, литеральные и “замкнутые” (‘(expression... )’, ‘[expression... ]’, ‘{key: value... }’, ‘‘expression‘’) выражения.

2. Первичные выражения: x.attribute, x[key], x[slice_list], x(arg_list).

3. ** (см. замечания в разделе 10.2.3).

4. Унарные операторы +, - и ~.

5. *, /, %.

6. Бинарные операторы + и -.

7. <<, >>.

8. &.

9. ^.

10. |.

11. Условные операторы: <, <=, >, >=, ==, !=, <>, is [not], [not] in.

12. not.

13. and.

14. or.

15. lambda.

16. expr1,... (образование списка выражений).

10.3 Простые инструкции Простые инструкции записываются в одну логическую строку. Логическая строка может содержать несколько простых инструкций разделенных точкой с запятой.

10.3. Простые инструкции 10.3.1 Инструкции-выражения Инструкции-выражения обычно используются для вычисления и вывода значения выра жения (в интерактивном режиме) или для вызова “процедур” — функций, возвращаю щих незначимый результат (None) и состоят из одного выражения (список выражений также является выражением).

В интерактивном режиме значение выражения, если оно не равно None, преоб разуется в строку аналогично тому, как это делает встроенная функция repr() и вы водится на стандартный поток вывода. Значение None не выводится — таким образом вызов процедур не дает никакого вывода.

10.3.2 Присваивание Присваивание (‘lvalue = expression’) используется для того, чтобы связать иден тификатор (существующий или новый) с объектом, для создания и изменения атрибутов объектов, изменения элементов изменяемых последовательностей, добавления и измене ния записей в отображениях. Присваивание может производиться (выражения, которые могут быть использованы слева от знака равенства, обычно называют lvalue):

name = expression Идентификатору.

x.attribute = expression Атрибуту. Обычно имя attribute в пространстве имен объекта x связывается с объектом, являющимся результатом вычисления выражения expression. Вы можете контролировать поведение при присваивании атрибуту экземпляра класса, определив для класса специальный метод setattr().

x[key] = expression Элементу последовательности или отображения. Изменение элементов экземпля ров классов реализуется специальным методом setitem().

x[slice_list] = expression Подпоследовательности (синтаксис списка срезов slice_list описан в разде ле 10.2.2). Выражение expression должно быть последовательностью. При сваивание срезу экземпляра контролируется с помощью специального метода setslice() (если используется простая запись среза) или setitem() (если используется расширенная запись срезов).

lvalue,... = expression (lvalue,... ) = expression [lvalue,... ] = expression Конструкции, используемой для создания кортежей и списков (в том числе, произ вольным образом вложенных) из всех перечисленных выражений. Операция при сваивания выполняется путем распаковки последовательностей. Результат вычис ления выражения expression должен быть последовательностью, содержащей 114 Глава 10. Синтаксис и семантика такое же количество элементов, какое указано слева от знака равенства. Каж дому вложенному списку слева в результате должна соответствовать подпоследо вательность с таким же количеством элементов. При несоответствии количества элементов генерируется исключение ValueError. Приведем несколько примеров:

>>> x = range(1) >>> y, = range(1) >>> print x, y [0] >>> class c:

... def init(self, val):

... self.val = val... def repr(self):

... return ’c(’+‘self.val‘+’)’...

>>> o = c(1) >>> l = range(3) >>> l[1], [(x, y), o.val] = [10, (xrange(2, 4), 5)] >>> print x, y, l, o 2 3 [0, 10, 2] c(5) Значение выражения справа от = (включая упаковку) вычисляется до того, как начинается присваивание. Таким образом, инструкция ‘a, b = b, a’ обменивает зна чения переменных a и b. Однако следующий пример выведет ‘[0, 2]’:

x = [0, 1] i = i, x[i] = 1, print x Начиная с версии 2.0, возможно одновременное выполнение арифметической или битовой операции и присваивания:

lvalue += expression lvalue -= expression lvalue *= expression lvalue /= expression lvalue %= expression lvalue **= expression lvalue &= expression lvalue |= expression lvalue ^= expression lvalue >>= expression lvalue <<= expression Если lvalue является неизменяемым объектом, инструкция ‘lvalue op= expression’ всегда эквивалентна последовательному применению оператора и присва 10.3. Простые инструкции иванию результата (нового объекта) lvalue (‘lvalue = lvalue op expression’).

Здесь, в отличие от обычного присваивания, lvalue не может быть кортежем.

Заметим, что формально присваивание в языке Python не является оператором, то есть, не возвращает значения и не может быть использовано в выражениях. Так сделано, например, чтобы избежать ошибочного использования = вместо == в инструкции if.

10.3.3 Инструкция del Семантика инструкции ‘del lvalue’ во многом схожа с семантикой присваивания (синтаксис lvalue описан в разделе 10.3.2). Удаление идентификатора удаляет при вязку имени (которое должно существовать) в локальном или глобальном простран стве имен (см. раздел 10.5) к объекту. При удалении атрибута обычно удаляется со ответствующее имя из пространства имен объекта. Вы можете контролировать пове дение при удалении атрибутов экземпляров, определив для класса специальный метод delattr(). Удаление элементов (записей) из экземпляров-последовательностей (экземпляров-отображений) реализуется специальным методом delitem(), под последовательности — специальным методом delslice() (если используется простая запись среза) или delitem() (при использовании расширенной записи срезов).

10.3.4 Пустая инструкция Инструкция pass ничего не делает и может быть полезна там, где инструкция требуется синтаксисом, однако нет необходимости в выполнении каких либо действий, например:

#, def do_nothing(arg): pass # class record: pass 10.3.5 Инструкция print Инструкция ‘print [expr_list]’ для каждого выражения в списке выражений expr_list вычисляет его значение и выводит строковое представление значения вы ражения на стандартный поток вывода, разделяя их пробелами (необходимость вывода пробела контролируется атрибутом softspace файлового объекта). Строковое пред ставление получается аналогично тому, как это делает встроенная функция str() (см.

раздел 12).

Если список выражений не заканчивается запятой, в конце выводится символ пе рехода на новую строку. Это единственное действие, которое выполняется, если ин 116 Глава 10. Синтаксис и семантика струкция содержит только ключевое слово print.

В качестве стандартного потока вывода используется файловый объект, на который ссылается переменная stdout в модуле sys. Если имя sys.stdout было удалено, генерируется исключение RuntimeError.

Начиная с версии 2.0, инструкция print может быть использована для вывода в любой файл. Для этого после ключевого слова print необходимо поставить >> и первое выражение в списке expr_list должно давать файловый объект или None (в этом случае для вывода будет использоваться sys.stdout). Например:

print >> sys.stderr, ’ !’ Инструкция print предъявляет следующие требования к файловому объекту, в который производится вывод: объект должен иметь метод write() и доступный для записи атрибут softspace (последнее всегда верно для экземпляров классов, не име ющих специальных методов getattr() и setattr()).

10.3.6 Инструкция break Инструкция break может быть использована только (синтаксически) внутри циклов for и while, но не в определении функции или класса, находящегося в цикле. Пре рывает выполнение самого вложенного цикла (пропуская ветвь else цикла, если она присутствует). При прерывании цикла for переменная (или переменные), в которой хранится значение текущего элемента, остается неизменной.

Если для выхода из цикла необходимо покинуть блок инструкции try с ветвью finally, перед выходом выполняется ветвь finally.

10.3.7 Инструкция continue Инструкция continue может быть использована только (синтаксически) внутри циклов for и while, но не в определении функции или класса, находящегося в цикле. В теку щих версиях инструкция continue также не может быть использована внутри основ ного блока инструкции try (расположенного синтаксически внутри цикла) — только в ветвях except и else2. Инструкция продолжает выполнение наиболее вложенного цикла со следующего прохода.

Это ограничение, возможно, будет снято в будущих версиях языка.

10.3. Простые инструкции 10.3.8 Инструкция return Инструкция ‘return [expression]’ (может быть использована синтаксически толь ко в определении функции) прерывает выполнение функции (при ее вызове) используя значение выражения expression (None, если выражение опущено) в качестве возвра щаемого функцией значения.

Если для возврата из функции необходимо покинуть блок инструкции try с ветвью finally, перед возвратом выполняется ветвь finally.

10.3.9 Инструкция global Инструкция ‘global identifier_list’ указывает на то, что идентификаторы identifier_list (список через запятую идентификаторов) во всем текущем блоке ссылаются на глобальные переменные. В то время как использование в выражениях глобальных имен производится автоматически, если они не определены (нигде в те кущем блоке) в локальном пространстве имен, присваивание глобальным именам без использования инструкции global невозможно.

Если имена где-либо в данном блоке кода указаны в инструкции global, их следу ет использовать только после этой инструкции. Такие имена не должны использоваться как формальные параметры циклов for, определений классов и функций и не должны быть среди имен, импортируемых инструкцией import. В текущих версиях инструк ции for, class и def изменяют глобальную переменную, а инструкция import не импортирует такие имена, однако в будущих версиях поведение может измениться.

Инструкция global является директивой синтаксическому анализатору команд и применяется только к единовременно компилируемому блоку кода. В частности, ин струкция global, содержащаяся в инструкции exec не оказывает влияния на блок кода, в котором содержится эта инструкция exec. И наоборот, инструкция global в блоке кода, содержащем также инструкцию exec, не оказывает влияние на код в этой инструкции exec. То же самое верно и для встроенных функций eval(), execfile() и compile().

10.3.10 Инструкция import Существует три формы записи инструкции import:

import module_list Импортирует указанные модули. module_list — список через запятую полных имен модулей (если модуль находится в пакете — используется запись через точку, например,..) с возможным указанием имен, к которым будут привязаны объекты-модули в локальном пространстве имен (см. ниже).

118 Глава 10. Синтаксис и семантика from module import obj_list Импортирует объекты из модуля module. obj_list — список через запятую идентификаторов объектов (идентификатор объекта может ссылаться, в том числе, и на объект-модуль, но, в отличие от имени модуля, не может использовать запись через точку) с возможным указанием имен, к которым будут привязаны объекты в локальном пространстве имен (см. ниже).

from module import * Импортирует все имена из модуля module, кроме имен, начинающихся с символа подчеркивания.

Инструкция import выполняется в два этапа:

1. Интерпретатор находит модуль (или модули) и, если это необходимо, инициализи рует его.

2. Связывает имена в текущем локальном пространстве имен с объектами-модулями (первая форма записи инструкции) или объектами, на которые ссылаются соответ ствующие имена в модуле.

Начиная с версии 2.0, Вы имеете возможность указать имя, к которому бу дет привязан объект в локальном пространстве имен, используя запись ‘object as local_name’ в списке модулей (module_list) или объектов (obj_list). Так, на пример, инструкция ‘import operator’ привязывает импортированный объект-модуль к локальному имени operator, в то время как ‘import operator as op’ привязы вает тот же объект-модуль к локальному имени op. Во избежание недоразумений не допускается импортирование под другим именем объектов, для которых используется точечная запись: вместо ‘import xml.sax as s’ необходимо использовать запись ‘from xml import sax as s’.

Под инициализацией модуля, реализованного на языке Python, подразумевается со здание пустого объекта-модуля, добавление его в таблицу sys.modules и выполнение в контексте этого модуля инструкций из файла ‘module.py’ (или ‘init.py’ в каталоге ‘module’, если модуль является пакетом). Точнее, выполняется его байт-компилированная версия — файл ‘module.pyc’ или ‘module.pyo’ в зависимости от того, используется оптими зация или нет. Если соответствующий байт-компилированный файл отсутствует или не соответствует исходному ‘.py’-файлу, интерпретатор компилирует исходный файл (если он содержит синтаксические ошибки, генерируется исключение SyntaxError и объект модуль в sys.modules не добавляется), пытается записать байт-компилированную вер сию и выполняет его (независимо от успешности записи байт-компилированной вер сии). Не перехваченные исключения во время инициализации прерывают процесс им портирования модуля. Однако частично инициализированный модуль остается в таблице sys.modules. Инициализация динамически подгружаемого или встроенного в интер претатор модуля выполняется путем вызова функции initmodule.

Система запоминает модули, которые были инициализированы в словаре (индек сированном именами модулей) sys.modules. При импортировании, если имя модуля найдено в sys.modules, его инициализация пропускается. Если Вы хотите заново 10.3. Простые инструкции инициализировать модуль (например, чтобы не покидать интерпретатор после каждо го внесения изменений в модуль при отладке), воспользуйтесь встроенной функцией reload().

Поиск модулей производится сначала среди встроенных в интерпретатор, затем в путях, хранящихся в списке sys.path. sys.path при запуске интерпретатора со держит текущий каталог, список каталогов из переменной окружения PYTHONPATH и зависящие от платформы пути по умолчанию. Если модуль с указанным именем не найден, генерируется исключение ImportError.

Импортируемые имена не должны использоваться в инструкции global в той же области видимости. В текущих реализациях такие имена просто не будут импортирова ны, однако в будущих версиях поведение может измениться.

Запись ‘from... import *’ рекомендуется использовать только в глобальной области видимости.

Вы можете изменить поведение инструкции import, переопределив встроенную функцию import(). При этом будут полезны средства, определенные в модуле imp.

10.3.11 Инструкция exec Инструкция ‘exec expression [in globals, [locals]]’ предназначена для ди намического выполнения кода. Выражение expression должно давать объект типа code, string или file (открытый для чтения). Если expression является объектом кода, инструкция exec просто выполняет его. Строка или файл считаются содержа щими инструкции языка Python, которые должны быть выполнены (если не содержат синтаксических ошибок).

Выражения globals и locals должны давать словари, которые будут исполь зованы как глобальное и локальное пространства имен. Если аргументы опущены, код выполняется в текущей области видимости. Если указан только аргумент globals, он используется в качестве глобального и локального пространств имен. В текущих реа лизациях в эти словари автоматически добавляется запись (если такой нет) с ключом ’builtins’, ссылающаяся на словарь пространства встроенных имен (то есть, модуля builtin).

Динамическое вычисление выражений осуществляется с помощью встроенной функции eval(). Также могут быть полезны встроенные функции globals() и locals(), которые возвращают словари, соответствующие текущим глобальному и ло кальному пространствам имен.

В текущих реализациях многострочные составные инструкции должны заканчи ваться переходом на новую строку. Так, ‘exec ’for i in (1,2):\n\tprint i\n’’ будет работать нормально, но при попытке выполнить ‘exec ’for i in (1,2):\n\tprint i’’ будет сгенерировано исключение SyntaxError.

120 Глава 10. Синтаксис и семантика 10.3.12 Отладочные утверждения Общепринятый способ включения в программу отладочных утверждений — инструк ция ‘assert expression [, exc_arg]’. Если выражение expression ложно, гене рируется исключение AssertionError. Если задан необязательный второй аргумент exc_arg, то он используется в качестве аргумента, передаваемого конструктору исклю чения. При компиляции с оптимизацией инструкции assert игнорируются.

Простая форма ‘assert expression’ эквивалентна конструкции (предполага ется, что идентификаторы debug и AssertionError ссылаются на встроенные переменные с такими именами;

встроенная переменная debug равна 1 при отклю ченной оптимизации) if debug:

if not expression: raise AssertionError() Расширенная форма ‘assert expression, exc_arg’ эквивалентна конструкции if debug:

if not expression: raise AssertionError(exc_arg) В качестве аргумента exc_arg можно, например, использовать строку, поясняю щую возможную причину невыполнения утверждения. Заметим, что нет необходимости включать в нее исходный текст выражения expression, так как он в любом случае бу дет включен в выводимую (если исключение не перехвачено) отладочную информацию.

10.3.13 Генерация исключений Инструкция ‘raise [expr1 [, expr2 [, expr3]]]’ следует использовать в случае возникновения ошибок и других исключительных ситуаций. Без аргументов инструкция raise повторно генерирует последнее исключение, сгенерированное в текущей области видимости.

Иначе вычисляется значение выражения expr1, которое должно быть строкой, классом или экземпляром класса. Если задан второй аргумент (выражение expr2), вы числяется его значение, в противном случае подставляется None. Если первый аргумент является объектом-классом и второй аргумент является экземпляром этого или произ водного от него класса, expr2 используется в качестве генерируемого исключения. Если же второй аргумент не является таким экземпляром, он используется для инициализа ции класса expr1 следующим образом: если выражение expr2 является кортежем, то оно используется в качестве списка аргументов;

если expr2 равно None, класс иници ализируется с пустым списком аргументов;

в остальных случаях expr2 используется как единственный аргумент при инициализации. Если же первый аргумент инструкции 10.4. Составные инструкции raise является экземпляром класса, он используется в качестве исключения (второй аргумент должен быть равен None или опущен).

Поддержка строк в качестве исключений существует лишь для совместимости со старыми версиями и может быть удалена в будущих версиях языка. И, тем не менее, если первый аргумент является строкой, он используется в качестве исключения. В этом случае второй аргумент (или None) является ассоциированным с исключением значением.

Третий аргумент, если задан и не равен None, должен быть объектом traceback (см. раздел 11.9.3). В этом случае он используется вместо объекта, создаваемого для текущего положения, для указания на место возникновения исключительной ситуации.

10.4 Составные инструкции Составные инструкции содержат другие инструкции и каким-либо образом управляют их выполнением. Обычно составные инструкции записываются в несколько логических строк с использованием отступов, хотя, если составная инструкция имеет только одну ветвь, тело которой содержит только простые инструкции, она может быть записаны в одну логическую строку.

Инструкции if, while и for реализуют традиционные средства управления логи кой программы. Инструкция try устанавливает обработчик исключений. Определения функций и классов также являются составными инструкциями.

Составная инструкция состоит из одной или нескольких ветвей. Каждая ветвь состоит из заголовка и тела. Заголовки ветвей одной составной инструкции должны иметь одинаковый уровень отступа. Заголовок каждой ветви начинаются уникальным ключевым словом и заканчиваются двоеточием. Тело является набором инструкций, управляемых данной ветвью. Тело может содержать одну или несколько разделенных точкой с запятой простых инструкций, записанных в одной логической строке с заго ловком (сразу после двоеточия), или одну или несколько произвольных инструкций на непосредственно следующих за заголовком стоках, имеющих по сравнению с заголов ком дополнительный отступ. Только вторая форма записи тела ветви может содержать составные инструкции. Следующий пример является недопустимым, в первую очередь потому, что не очевидно, к какой из инструкций if должна была бы относиться ветвь else:

if test1: if test2: print x Логическая строка не может содержать несколько инструкций, если хотя бы одна из них является составной. В следующем примере все инструкции print входят в тело основной ветви инструкции if:

if x < y < z: print x;

print y;

print z 122 Глава 10. Синтаксис и семантика Обратите внимание, что каждая ветвь любой составной инструкции всегда за канчиваются переходом на новую строку. Кроме того, во избежание неоднозначностей, дополнительные ветви всегда начинаются с ключевого слова, которое никогда не исполь зуется в начале инструкций. Характерная для таких языков, как C, проблема отнесения ветви else решается в языке Python требованием правильного использования отступов во вложенных составных инструкциях.

10.4.1 Инструкция if Инструкция if используется для выполнения различных действий в зависимости от условий:

if expr1: suite [elif expr2: suite2...] [else: suite0] Инструкция if вычисляет одно за другим выражения exprN в основной ветви и необязательных ветвях elif до тех пор, пока не будет получена истина, и выполняет соответствующий ему блок кода (вся оставшаяся часть инструкции if пропускается).

Если все выражения дают ложь, выполняется блок кода suite0 необязательной ветви else.

10.4.2 Цикл while Цикл while используется для многократного выполнения действий, пока выполняется условие:

while expr: suite [else: suite2] Инструкция while выполняется в следующем порядке:

1. Вычисляется выражение expr и, если оно дает ложь, переходит к пункту 3.

2. Выполняется блок кода suite1. При этом выполнение в блоке инструкции break немедленно прерывает выполнение цикла (пункт 3 не выполняется), а выполнение инструкции continue прерывает выполнение блока кода, после чего выполнение цикла продолжается с пункта 1. После окончания выполнения блока suite1, вы полнение цикла продолжается с пункта 1.

3. Выполняется блок кода suite2 (ветвь else). Инструкции break и continue в этом блоке считаются относящимися к внешнему циклу.

10.4. Составные инструкции 10.4.3 Цикл for Инструкция for используется для перебора элементов последовательности:

for lvalue in sequence: suite [else: suite2] Выражение sequence вычисляется один раз и должно давать последовательность (объект, для которого определена операция получения элемента по индексу;

если ин декс выходит за пределы диапазона, должно генерироваться исключение IndexError).

Для каждого элемента последовательности sequence в порядке возрастания индексов, начиная с 0, выполняется присваивание lvalue элемента (на элемент item и параметр lvalue распространяются обычные правила, действующие при выполнении инструкции присваивания ‘lvalue = item’;

см. раздел 10.3.2) и выполняется блок кода suite1.

После того как последовательность исчерпана (определяется по сгенерированному ис ключению IndexError), если присутствует ветвь else, выполняется блок suite2.

Выполнение инструкции break в блоке suite1 немедленно прерывает выполне ние цикла (ветвь else игнорируется). При выполнении инструкции continue в блоке suite1 пропускается остаток блока и выполнение цикла продолжается после присва ивания lvalue следующего элемента последовательности sequence или выполняется ветвь else, если в последовательности нет следующего элемента.

Вы можете присваивать переменной или переменным, входящим в lvalue, — это никак не отразится на следующем элементе, который будет присвоен lvalue. Перемен ные, входящие в lvalue не удаляются после окончания выполнения цикла и сохраняют последние присвоенные им значения. Однако, если последовательность sequence пу стая, lvalue не будет присвоено никакое значение (таким образом, используя эти пере менные без дополнительной проверки, Вы имеете шанс получить ошибку NameError).

См. также описания встроенных функций range() и xrange() в главе 12.

Будьте внимательны, изменяя последовательность, элементы которой Вы перебира ете. Текущий элемент последовательности определяется значением внутреннего счетчи ка. Конец последовательности определяется по исключению IndexError при попытке получить очередной элемент. Таким образом, если в блоке suite1 Вы удалите теку щий или один из пройденных элементов последовательности, следующий элемент будет пропущен. Аналогично, если вы добавите в последовательность новый элемент перед текущим, тело цикла для текущего элемента будет выполнено еще раз. Такое поведе ние может привести к неприятным ошибкам, которых обычно можно избежать, если перебирать элементы копии исходной последовательности, например:

for x in a[:]:

if x < 0: a.remove(x) 124 Глава 10. Синтаксис и семантика 10.4.4 Инструкция try Существует две формы инструкции try. Их нельзя смешивать (то есть, инструкция try не может содержать одновременно ветви except и finally), однако могут быть вложенными друг в друга.

С помощью первой формы Вы определяете обработчики исключений:

try: suite except [exc_class1 [, lvalue1]]: suite [...] [else: suite0] Сначала выполняется тело основной ветви — suite1, и если код не генериру ет исключение, выполняется блок suite0 (необязательная ветвь else). Если же код в блоке suite1 генерирует исключение, последовательно проверяются (в порядке их следования) ветви except до тех пор, пока не будет найдена ветвь except, удовле творяющая сгенерированному исключению. Ветвь except без аргументов, если при сутствует, должна быть последней ветвью except (в противном случае генерируется исключение SyntaxError) — удовлетворяет всем исключениям. Если указано выра жение exc_classN, оно вычисляется и ветвь считается удовлетворяющей исключение, если полученный объект совместим с исключением. Объект exc_classN является сов местимым с исключением, если исключение является экземпляром класса exc_classN или производного от него класса или является строкой равной exc_classN. Объект exc_classN также является совместимым с исключением, если он является кортежем, содержащим объект, совместимый с исключением (при этом кортеж может содержать вложенные кортежи).

Если ни одна из ветвей except не удовлетворяет исключению, поиск обработчика продолжается во внешнем блоке try (если такой имеется) и т. д. Если исключение ге нерируется при вычислении выражения exc_classN, обработка исходного исключения прекращается и производится поиск обработчика нового исключения во внешнем блоке (как будто вся инструкция try сгенерировала исключение).

Если найдена ветвь except, удовлетворяющая исключению, исключение (если оно является экземпляром класса) или ассоциированное с ним значение (если исключение является строкой) присваивается параметру lvalueN (любое выражение, которому до пускается присваивание — см. раздел 10.3.2), если он задан, выполняется блок кода ветви (suiteN) и выполнение продолжается инструкций следующих за инструкцией try (исключение считается обработанным). Таким образом, если имеется две вложен ных инструкции try и исключительная ситуация возникла в блоке try внутренней инструкции, обработчик внешней инструкции не будет обрабатывать исключение.

Перед выполнением блока ветви except информация об исключении сохраняется и может быть получена с помощью функции sys.exc_info() — функция возвращает кортеж, состоящий из типа исключения (класс или строка), самого исключения (если 10.4. Составные инструкции оно является экземпляром класса) или ассоциированного значения (если исключение является строкой) и объекта traceback (см. раздел 11.9.3). Эти же значения сохра няются в sys.exc_type, sys.exc_value и sys.exc_traceback соответственно.

Однако их не рекомендуется использовать, так как это небезопасно в многопоточных программах.

Необязательная ветвь else выполняется, если в блоке основной ветви не было сгенерировано исключение. Если при выполнении ветви except или else генерируется исключение, поиск обработчика производится во внешней инструкции try (если такая имеется), а не в текущей.

Вторая форма используется для определения “страховочного” кода:

try: suite finally: suite Сначала выполняется ветвь try (блок suite1). Если при этом не возникает исключи тельной ситуации, далее просто выполняется ветвь finally (блок suite2). Если же в блоке suite1 генерируется исключение, то оно временно сохраняется, выполняет ся ветвь finally и сохраненное исключение генерируется снова (поиск обработчика производится во внешней инструкции try, если такая имеется). Если Вы прерываете выполнение блока suite2 инструкцией return, break или continue или генерируя новое исключение, сохраненное исключение будет утрачено (то есть не будет сгенери ровано снова).

Ветвь finally выполняется и в том случае, если выход из блока suite1 про исходит по инструкции return или break. В текущих реализациях использование инструкции continue в основной ветви инструкции try не допускается (ситуация, возможно, изменится в будущих версиях).

10.4.5 Определение функций С помощью инструкции def Вы можете определить объект-функцию (function, см.

раздел 11.4.1):

def func_name(param_list): suite param_list — список параметров (через запятую;

если параметры записаны с исполь зованием только первой и второй форм, список может содержать завершающую запятую, которая игнорируется) в следующих формах (различные формы можно смешивать, но каждая из них может использоваться только один раз и порядок их следования должен быть именно таким, в котором они перечислены):

param1 [, param2...] Список простых позиционных параметров. Каждый из параметров может 126 Глава 10. Синтаксис и семантика быть идентификатором или подсписком параметров в виде ‘(subparam1 [, subparam2...])’ (подсписки аргументов также могут содержать вложенные подсписки).

param1 = expr1 [, param2 = expr2...] Список позиционных аргументов paramN, имеющих значение по умолчанию, по лучаемое вычислением выражения exprN. Форма записи параметров такая же, как и для первой формы записи аргументов. Выражения exprN вычисляются один раз — при выполнении определения функции, в области видимости, которое со держит определение функции.

*indentifier Получение произвольного числа позиционных аргументов. Переменной indentifier присваивается кортеж всех позиционных аргументов, которым не соответствует параметры, заданные с использованием первых двух форм.

**indentifier Получение произвольного количества именованных аргументов. Переменной indentifier присваивается словарь всех именованных аргументов, которым не соответствуют параметры, заданные с использованием первых двух форм.

При каждом выполнении определения функции (инструкции def) создается объект-функция и привязывается к имени func_name (идентификатор) в локальном пространстве имен (не рекомендуется использовать в качестве func_name идентифи катор, который указан в этом блоке в инструкции global — см. раздел 10.3.9). Со здаваемый объект-функция содержит ссылку на текущее глобальное пространство имен, которое будет использоваться в качестве глобального пространства имен при вызове функции.

Определение функции не выполняет тело функции (suite) — оно выполняется только при вызове функции. Аргументы, соответствующие параметрам со значением по умолчанию, могут быть опущены. В этом случае подставляется значение по умолчанию.

Синтаксис и семантика вызова функций описана в разделе 10.2.2. При вызове зна чения присваиваются всем параметрам, указанным в списке: это может быть значение позиционного или именованного аргумента или значение по умолчанию. Параметры, записанные в виде *identifier и **identifier, если присутствуют, инициализи руются пустыми кортежем и словарем соответственно.

Для создания простой анонимной функции вы можете воспользоваться оператором lambda (см. раздел 10.2.7).

Функция (в том числе, и созданная с помощью оператора lambda) не имеет до ступа к локальному пространству имен блока, в котором она определена. Чтобы обойти это ограничение, часто используют значения аргументов по умолчанию:

#,, # n def make_incrementer(n):

10.4. Составные инструкции def increment(x, n=n):

return x+n return increment add1 = make_incrementer(1) print add1(3) # ’4’ Как мы уже упоминали, значения по умолчанию вычисляются только один раз.

Это особенно важно, если значение по умолчанию является изменяемым объектом (на пример, списком или словарем): если функция изменяет объект (например, добавляя элемент в список), изменяется значение по умолчанию. Обычно это не то, что Вы ожи даете. Один из способов обойти такое поведение — использовать в качестве значения параметра по умолчанию объект None и явно проверять его в теле функции:

def add_ostrich_notice(notices=None):

if notices is None:

notices = [] notices.append( " - ") return notices Однако использовать такое поведение для определения статических переменных нежелательно — лучше использовать глобальные переменные модуля или определить класс со специальным методом call(), например:

# #, # ’from... import *’ _MAX_KICKS_ALLOWED = 10 # class _dog_kicker:

def init(self):

# # "" kick_a_dog() self.num_of_kicks = def call(self, num=1):

if self.num_of_kicks >= _MAX_KICKS_ALLOWED:

print " ?" return num = min(_MAX_KICKS_ALLOWED-self.num_of_kicks, num) self.num_of_kicks = self.num_of_kicks+num print " ", num, "()" # kick_a_dog = _dog_kicker() 128 Глава 10. Синтаксис и семантика 10.4.6 Определение класса Определение класса создает объект-класс (class, см. раздел 11.6.1):

class class_name[(base_classes)]: suite Здесь base_classes — список выражений (см. раздел 10.2.8), каждое из которых должно давать объект-класс. Для класса создается новое локальное пространство имен, глобальное пространство имен используется текущее (то есть того блока кода, в котором находится определение класса) и в этом окружении выполняется блок suite (обычно содержит только определения функций). После выполнения блока suite локальное про странство имен класса (используется для создания словаря атрибутов класса) и список базовых классов (значения выражений, входящих в base_classes) сохраняется в со зданном объекте-классе и объект-класс привязывается к имени class_name в текущем локальном пространстве имен.

Имена, определенные в пространстве имен класса являются атрибутами класса — общими для всех экземпляров класса. Для того, чтобы определить атрибут экземпля ра класса (имя в пространстве имен экземпляра класса), необходимо присвоить ему значение в одном из методов (например, при инициализации экземпляра — в методе init()). И атрибуты класса, и атрибуты экземпляра доступны с использовани ем записи через точку (instance.name) — атрибуты экземпляра “прячут” атрибуты класса с таким же именем. Атрибуты класса, значение которых равно неизменяемому объекту, могут служить как значения по умолчанию для атрибутов экземпляров этого класса.

10.5 Пространства имен Пространство имен — отображение имен (идентификаторов) к объектам. По функци ональности пространства имен эквивалентны словарям и реализуются в виде словарей.

В языке Python всегда присутствуют три пространства имен: локальное, глобаль ное и пространство встроенных имен. Поиск локальных имен всегда производится в локальном пространстве имен, глобальных — сначала в глобальном, затем в простран стве встроенных имен3.

Является ли имя локальным или глобальным определяется в момент компиляции:

в отсутствии инструкции global, имя, добавляемое где-либо в блоке кода, является локальным во всем блоке;

все остальные имена считаются глобальными. Инструкция global позволяет заставить интерпретатор считать указанные имена глобальными.

Если блок программы содержит инструкцию exec или ‘from... import *’, семантика локальных имен изменяется: сначала производится их поиск в локальном пространстве имен, затем в глобальном и пространстве встроенных имен.

10.5. Пространства имен Имена могут быть добавлены (только в локальное пространство имен) следующими способами:

• передача формальных аргументов функции, • использование инструкции import, • определение класса или функции (добавляет в локальное пространство имен имя класса или функции), • использование оператора присваивания, • использование цикла for (в заголовке указывается новое имя), • указывая имя во второй позиции после ключевого слова except.

Если глобальное имя не найдено в глобальном пространстве имен, его поиск про изводится в пространстве встроенных имен, которое, на самом деле, является простран ством имен модуля builtin. Этот модуль (или словарь определенных в нем имен) доступен под глобальным именем текущего блока builtins. Если же имя не най дено в пространстве встроенных имен, генерируется исключение NameError.

Ниже приведены значения локального и глобального пространств имен для раз личных типов блоков кода. Пространство имен модуля автоматически создается, когда модуль импортируется первый раз.

Тип блока Глобальное Локальное пространство имен пространство имен Модуль (программа и ин- пространство имен модуля то же, что и глобальное терактивные команды фак тически являются модулем main) Класс пространство имен модуля, новое пространство имен в котором находится опре- (пространство имен клас деление класса са), создается в момент вы полнения определения Функция (если объект ко- пространство имен модуля, новое пространство имен да, представляющий те- в котором находится опре- (пространство имен функ ло функции, выполняет- деление функции ции), создается каждый раз ся с помощью инструк- при вызове функции ции exec, Вы можете са ми определить, какие про странства имен использо вать) Выражение, вычисляе- глобальное пространство локальное пространство мое с помощью функции имен блока, из которого имен блока, из которого вызывается функция вызывается функция input() 130 Глава 10. Синтаксис и семантика Тип блока Глобальное Локальное пространство имен пространство имен Строка, файл или объект по умолчанию использу- по умолчанию использу кода, выполняемые с по- ется глобальное простран- ется локальное простран мощью инструкции exec, ство имен блока, в кото- ство имен блока, в кото ром выполняется инструк- ром выполняется инструк или функций eval() ция или из которого вызы- ция или из которого вызы или execfile() (ис вается функция вается функция пользуя необязательные аргументы, Вы можете сами определить, какие пространства имен исполь зовать) Встроенные функции globals() и locals() возвращают словарь, представляю щий глобальное и локальное пространства имен соответственно (см. главу 12).

Глава Встроенные типы данных В этом разделе описываются стандартные типы данных, поддержка которых встроена в интерпретатор: числа, последовательности и другие, включая сами типы. В языке Python нет явного логического типа — используйте целые числа.

Некоторые операции поддерживаются всеми объектами;

в частности, любые объ екты можно сравнивать, проверять их истинность (см. разделы 10.2.4 и 10.2.5) и для любых объектов можно получить строковое представление с помощью встроенных функ ций repr() (или используя запись в обратных кавычках: ‘expression‘) и str().

Объекты встроенных типов могут иметь следующие специальные атрибуты:

methods Список имен статических методов объекта. Атрибут определен только, если объект имеет хотя бы один такой метод.

members Список имен статических атрибутов данных объекта. Атрибут определен только, если объект имеет хотя бы один такой атрибут.

При каждом обращении к атрибутам methods и members создается новая копия списка.

11.1 Числовые типы В языке Python есть четыре типа чисел: целые (int), длинные целые (long int), с плавающей точкой (вещественные;

float) и комплексные (complex).

Числа создаются с использованием литералов или как возвращаемый результат встроенной функции или оператора. Числовые литералы в чистом виде (включая шест надцатеричные и восьмеричные) дают простые целые числа.

Python полностью поддерживает смешанную арифметику: если бинарный арифме тический оператор имеет операнды разного типа, операнд “меньшего” типа приводится к типу другого операнда (int < long int < float < complex). Это же правило используется для сравнения чисел разного типа1. Для приведения чисел к нужному типу В результате, например, списки [1, 2] и [1.0, 2.0] считаются равными.

132 Глава 11. Встроенные типы данных Вы можете использовать встроенные функции int(), long(), float() и complex().

При приведении числа с плавающей точкой к целому (простому или длинному) типу, число округляется в сторону нуля (см. также функции floor() и ceil() в модуле math).

11.1.1 Целые и длинные целые числа Целые числа реализованы с использованием типа long в C, поддерживающего числа в диапазоне не менее чем от -2 147 483 647 до 2 147 483 647. Длинные целые имеют неогра ниченную точность.

Литералы целых чисел могут быть записаны в десятичном, восьмеричном и шестна дцатеричном виде. Десятичная запись состоит из идущих подряд десятичных цифр (0– 9), причем первая цифра не может быть нулем. Восьмеричная запись образуется из нуля и следующих за ним восьмеричных цифр (0–7). Шестнадцатеричная запись образуется из приставки ‘0x’ или ‘0X’ и следующих за ней шестнадцатеричных цифр (0–9, a–z, A–Z). Знак ‘-’ или ‘+’ не является частью литерала, а лишь унарным оператором, при меняемым к объекту после его создания. Если литерал представляет число, выходящее за пределы диапазона допустимых чисел, генерируется исключение OverflowError.

Целые литералы с суффиксом ‘L’ или ‘l’ дают длинные целые (лучше использовать ‘L’, из-за схожести символа ‘l’ с единицей).

Приведем несколько примеров литералов для целых и длинных целых чисел:

7 2147483647 0177 0x 3L 79228162514264337593543950336L 0377L 0x100000000L 11.1.2 Вещественные числа Вещественные числа (числа с плавающей точкой) реализованы с использованием типа double в C (не менее 10 значащих цифр, наибольшее представимое число не меньше 1037).

Запись литералов вещественных чисел состоит из десятичных цифр (первая цифра не может быть нулем) и содержит десятичную точку и/или экспоненциальную часть.

Экспоненциальная часть начинается с символа ‘e’ или ‘E’, далее следует необязательный знак (‘+’ или ‘-’) и одна или несколько десятичных цифр.

Приведем несколько примеров литералов для чисел с плавающей точкой:

3.14 10..001 1e100 3.14e- Поведение в случаях, когда результат вычисления выражения не может быть пред ставлен в рамках типа float, зависит от поведения лежащей в основе библиотеки язы ка C. Обычно существуют значения, представляющие (отрицательные и положительные) 11.1. Числовые типы бесконечно малые и бесконечно большие числа. Строковое представление таких чисел зависит от версии интерпретатора и используемой для реализации библиотеки языка C, например, они могут выводиться как 1. или -1. c добавлением комментария #INF, #IND или #QNAN.

11.1.3 Комплексные числа Комплексные числа имеют мнимую и вещественную части, реализованные с использова нием типа double в C. Литералы мнимого числа создаются путем добавления суффикса ‘j’ или ‘J’ к десятичной записи целого или вещественного числа. Например:

3.14j 10.j 10j.001j 1e100j 3.14e-10j Комплексные числа с ненулевой вещественной частью создаются сложением веще ственной и мнимой частей или с помощью встроенной функции complex() (см. главу 12).

Комплексные числа имеют два атрибута данных и один метод:

real Действительная часть комплексного числа.

imag Мнимая часть комплексного числа.

conjugate() Возвращает комплексное число, сопряженное с данным.

Преобразование комплексных чисел к другим числовым типам неоднозначно: для получения действительной части используйте атрибут real, а абсолютной величины — встроенной функцией abs().

11.1.4 Арифметические операторы Ниже приведены арифметические операторы, применимые ко всем числам:

x + y Сумма x и y.

x - y Разница между x и y.

x * y Произведение x на y.

134 Глава 11. Встроенные типы данных x / y Частное x и y. Если оба операнда целые (простые или длинные), то результат тоже будет целым. Результат всегда округляется в меньшую сторону: 1/2 и -1/-2 даст 0, а -1/2 и 1/-2 даст -1.

x % y Остаток от деления x на y.

-x x с противоположным знаком.

+x x (без изменений).

x ** y x в степени y.

Кроме того, для работы с числами Python предоставляет встроенные функции abs(), divmod() и pow() (см. главу 12), а также более сложные функции, опре деленные в модуле math.

11.1.5 Битовые операции над целыми числами Для простых и длинных целых чисел в языке Python определены битовые операторы.

Приоритет у всех бинарных битовых операторов ниже, чем у арифметических, и выше, чем у операторов сравнения. Унарный оператор ~ имеет такой же приоритет, как и унарные арифметические операторы (+ и -).

Ниже приведены все битовые операторы:

x | y Битовое ИЛИ x и y.

x ^ y Битовое исключающее ИЛИ x и y.

x & y Битовое И x и y.

x << n Биты x, сдвинутые на n влево, эквивалентно умножению на 2**n без контроля переполнения. Сдвиг на отрицательное число бит не допускается (генерируется исключение ValueError).

x >> n Биты x, сдвинутые на n вправо, эквивалентно (целочисленному) делению на 2**n без контроля переполнения. Сдвиг на отрицательное число бит не допускается (генерируется исключение ValueError).

~x Биты x инвертированные.

11.2. Последовательности 11.2 Последовательности В языке Python есть пять встроенных типов последовательностей: string, unicode, tuple, xrange, buffer и list.

Ниже приведены операции, определенные для всех последовательностей. Операто ры in и not in имеют такой же приоритет, как и операторы сравнения, а операторы + (бинарный) and * — такие же, как и соответствующие арифметические операторы2.

Выражения s и t — последовательности одинакового3 типа, n, i и j — целые.

len(s) Возвращает число элементов последовательности s.

x in s 1, если элемент x содержится в последовательности s, иначе — 0.

x not in s 0, если элемент x содержится в последовательности s, иначе — s + t Объединение последовательностей s и t.

s * n n * s n копий последовательности s объединенных вместе. Отрицательные значения n воспринимаются как 0 (что дает пустую последовательность такого же типа, как и s).

s += t s *= t Эквивалентно ‘s = s + t’ и ‘s = s * n’ соответственно, но, если s является изменяемой последовательностью, то выполнение операции будет производиться без создания нового объекта, то есть переменная s будет ссылаться на один и тот же объект до и после операции.

s[i] i-й элемент последовательности s, отсчет начинается с 0. Если индекс i имеет от рицательное значение, отсчет ведется с конца, то есть подставляется len(s) + i.

Однако -0 означает 0. Если индекс i указывает за пределы последовательности, генерируется исключение IndexError.

s[[i]:[j]] Срез последовательности s от i до j — подпоследовательность, содержащая эле менты последовательности s с такими индексами k, которые удовлетворяют нера венству i <= k < j. Если i или j имеет отрицательное значение, отсчет ведется с конца, то есть подставляется len(s) + i или len(s) + j. Индексы i и j мо гут быть опущены: i по умолчанию равен 0, j — sys.maxint. Если (после всех преобразований) первый индекс больше или равен второму, возвращается пустая последовательность.

Это необходимо, так как синтаксический анализатор не может определить тип операндов.

Последовательности, определяемые пользователем, могут не иметь этого ограничения.

136 Глава 11. Встроенные типы данных Для работы с последовательностями также могут быть полезны встроенные функ ции min() и max() (см. главу 12).

11.2.1 Строки В этом разделе описаны свойства обычных строк. Однако они в основном характерны и для строк Unicode.

Строковые литералы Строки могут быть заключены в одинарные (‘’’) или двойные (‘"’) кавычки (открываю щая и закрывающая кавычки должны быть одинаковыми) — так называемые короткие строки. Для длинных строк более удобна другая запись — строка, заключенная в груп пы из трех одинарных или трех двойных кавычек (открывающая и закрывающая группы должны быть одинаковыми). Короткие строки могут содержать управляющие последо вательности и любые символы, кроме обратной косой черты (‘\’), символов перехода на новую строку и кавычек, в которые строка заключена. Длинные строки дополнительно могут содержать символы перехода на новую строку и любые кавычки, хотя и не могут содержать группу из трех кавычек, в которые строка заключена.

В строках можно использовать следующие управляющие последовательности:

Последовательность Представляемый символ \newline Игнорируется (newline — символ новой строки).

\\ Символ обратной косой черты (‘\’).

\’ Одинарная кавычка (‘’’).

\" Двойная кавычка (‘"’).

\a Символ оповещения (BEL).

\b Символ возврата на одну позицию (backspace, BS).

\f Символ подачи страницы (formfeed, FF).

\n Символ перехода на новую строку (linefeed, LF).

\r Символ возврата каретки (CR).

\t Символ горизонтальной табуляции (TAB).

\v Символ вертикальной табуляции (VT).

\ooo ASCII символ с восьмеричным кодом, равным ooo.

\xhh... ASCII символ с шестнадцатеричным кодом, равным hh....

В соответствии со стандартом C, в последних двух управляющих последовательно стях воспринимается до трех восьмеричных цифр и неограниченное количество шестна 11.2. Последовательности дцатеричных цифр соответственно (на платформах с 8-битным типом char используются только младшие 8 бит). В отличие от стандарта C, все нераспознанные управляющие последовательности остаются в строке (включая символ обратной косой черты). Такое поведение очень удобно при отладке.

Перед открывающей кавычкой (или группой из трех кавычек) в строковом литера ле может быть указана буква ‘r’ или ‘R’. Такие строки называют “необрабатываемыми”, для них используются другие правила обработки управляющих последовательностей:

строка всегда будет состоять из тех символов, которые записаны между открывающей и закрывающей кавычками (или группами кавычек). Так, r"\n" даст строку, состоящую из двух символов — обратной косой черты и латинской буквы ‘n’, r"\"" также явля ется правильным строковым литералом и представляет строку, состоящую из символов обратной косой черты и двойной кавычки. Обратите внимание, что строка не может за канчиваться на нечетное количество символов обратной косой черты: последний из них образует с закрывающей кавычкой управляющую последовательность. Например, r"\" не является правильным строковым литералом.

Несколько следующих друг за другом строковых литералов, возможно разделенных символами пропуска (whitespace), использующие различную запись (заключены в раз личные кавычки;

обычные строки и необрабатываемые), автоматически объединяются.

Таким образом, строка ’’ "" является эквивалентом строки ’ ’. Строки объединяются даже в том случае, если одна из них является обычной строкой, а другая строкой Unicode (’a’ u’b’ == u’ab’). Эта особенность позволяет уменьшить количество используемых символов обратной косой черты при записи длин ного строкового литерала в несколько строк программного кода и даже снабдить части строк комментариями:

re.compile("[A-Za-z_]" # # "[A-Za-z0-9_]*" #, # ) Заметим, что объединение строковых литералов выполняется в момент компиля ции, в то время как оператор + объединяет строки во время выполнения программы.

Оператор форматирования Оператор % с объектом-строкой (string или unicode) в качестве левого аргумента имеет особое значение. Он воспринимает левый аргумент как строку формата, которую необходимо применить к правому аргументу (аналогично функции sprintf() в С), и возвращает полученную в результате форматирования строку.

Правый аргумент должен быть кортежем, содержащим по одному элементу на каждый аргумент, требуемый строкой формата. Если строке формата необходим один аргумент, правым аргументом оператора % может быть также требуемый строкой фор 138 Глава 11. Встроенные типы данных мата объект, если он не является кортежем4.

Строка форматирования может содержать обычные символы (кроме символа ‘%’), которые копируются без изменения, и описания формата. Каждое описание формата имеет вид: ‘%[... ][][.]_’5.

После символа ‘%’ могут быть указаны следующие флаги:

Флаг Назначение # Используется альтернативное представление аргумента. Для форматов ‘o’, ‘x’ и ‘X’ результат будет начинаться с ‘0’, ‘0x’ и ‘0X’ соответственно. При использовании форматов ‘f’, ‘g’ и ‘G’ результат всегда будет содержать десятичную точку, даже если после нее не следует не одной цифры. Кроме того, для форматов ‘g’ и ‘G’ из результата не будут удалены завершающие нули. В остальных случаях результат остается неизменным.

0 Результат заполняется слева нулями до нужной ширины поля. Для ‘s’- и ‘%’-форматов игнорируется.

- Результат выравнивается влево (по умолчанию результат выравнивается вправо).

Перед положительным числом вставляется пробел при использовании зна ковых форматов.

+ Перед числом всегда ставится знак (‘+’ или ‘-’) при использовании знако вых форматов.

Следующие два необязательных параметра — минимальная ширина поля и точ ность. Если представление значения содержит меньше символов, чем ширина поля, то оно будет дополнено пробелами (нулями). Точность задает минимальное количество цифр при использовании форматов ‘d’, ‘i’, ‘o’, ‘u’, ‘x’ и ‘X’ (по умолчанию 1), число цифр после десятичной точки для форматов ‘e’, ‘E’ и ‘f’ (по умолчанию 6), максимальное количество значащих цифр для форматов ‘g’ и ‘G’ (по умолчанию 6;

0 воспринимается как 1), максимальное количество символов из строки для формата ‘s’ игнорируется.

Вместо того, чтобы прямо указывать ширину поля и/или точность, Вы можете исполь зовать символ ‘*’. В этом случае соответствующее целое значение передается в кортеже аргументов:

>>> import math >>> R = >>> print " %*.*f" % (... 5, #... 2, #... 2*math.pi*R) # 6. Кортеж в этом случае должен содержать один элемент.

Перед символом формата может быть также указан модификатор длины (‘h’, ‘l’ или ‘L’), однако он игнорируется.

11.2. Последовательности Отрицательная ширина поля воспринимается как флаг ‘-’ и следующее за ним поло жительное число. Если значение после ‘.’ не указано или оно отрицательное, точность считается равной нулю.

Интерпретатор Python поддерживает следующие символы формата:

Символ Назначение d, i Десятичное представление целого числа (знакового) o Восьмеричное представление целого числа без знака u Десятичное представление целого числа без знака x Шестнадцатеричное представление целого числа без знака. Используются буквы в нижнем регистре (abcdef).

X Шестнадцатеричное представление целого числа без знака. Используются буквы в верхнем регистре (ABCDEF).

e Экспоненциальное представление вещественного числа. Экспоненциальная часть обозначается буквой ‘e’.

E Экспоненциальное представление вещественного числа. Экспоненциальная часть обозначается буквой ‘E’.

f Представление вещественного числа. Если точность равна 0, десятичная точка не используется. Во избежание вывода бесконечных строк бессмыс ленных цифр, точность ограничена числом 50.

g Если порядок вещественного числа меньше -4 или больше или равен точности, используется ‘e’-формат, в противном случае используется ‘f’ формат. Завершающие нули из дробной части удаляются.

G Если порядок вещественного числа меньше -4 или больше или равен точности, используется ‘E’-формат, в противном случае используется ‘f’ формат. Завершающие нули из дробной части удаляются.

r Строковое представление объекта, полученное аналогично применению встроенной функции repr(). Поддерживается, начиная с версии 1.6.

s Вставка строки или строкового представления объекта, полученного ана логично применению встроенной функции str().

% Символ ‘%’.

Если тип значения для ширины поля или точности не является int (при использо вании ‘*’), генерируется исключение TypeError. Остальные аргументы, не являющиеся строками и тип которых не соответствует используемому формату, интерпретатор пыта ется привести к необходимому типу с помощью соответствующих встроенных функций.

Если это не удается, то генерируется исключение TypeError (для встроенных типов) или AttributeError (для объектов типа instance).

В качестве правого аргумента оператора % можно использовать словарь (или любое другое отображение). В этом случае описания формата сразу после символа ‘%’ должны 140 Глава 11. Встроенные типы данных содержать заключенный в скобки ключ, соответствующий необходимому значению в словаре. Например:

>>> count = >>> language = ’Python’ >>> print ’ %(language)s %(count)03d ’ \ ’.’ % vars() Python 002.

Однако при такой записи Вы не можете передать ширину поля или точность в качестве аргумента (то есть, использовать ‘*’ в описании формата).

Методы строк Начиная с версии 1.6, строки (обычные и Unicode) имеют набор методов для работы с ними. В более ранних версиях Вы можете воспользоваться функциями, определенными в стандартном модуле string. Далее s — строка, к которой применяется метод.

Форматирование center(width) Возвращает строку длиной width, в центре которой расположена исходная стро ка (центрирует строку в поле заданной ширины). Строка дополняется до нужной длины пробелами. Если width меньше длины исходной строки, она возвращается без изменений.

ljust(width) Возвращает копию исходной строки, дополненную справа пробелами (выравнива ет строку влево в поле заданной ширины). Если width меньше длины исходной строки, она возвращается без изменений.

rjust(width) Возвращает копию исходной строки, дополненную слева пробелами (выравнивает строку вправо в поле заданной ширины). Если width меньше длины исходной строки, она возвращается без изменений.

Поиск вхождений count(sub [, start [, end]]) Возвращает количество вхождений подстроки sub в s[start:end]. Необязатель ные аргументы start и end интерпретируются так же, как и в операции среза (раздел 11.2).

11.2. Последовательности endswith(suffix [, start [, end]]) Возвращает 1, если строка s[start:end] заканчивается на suffix, иначе воз вращает 0.

find(sub [, start [, end]]) Возвращает наименьший индекс в исходной строке s начала вхождения подстроки sub в s[start:end]. Необязательные аргументы start и end интерпретиру ются так же, как и в операции среза (раздел 11.2). Если подстрока не найдена, возвращает -1.

index(sub [, start [, end]]) Аналог метода find(), генерирующий исключение, если подстрока не найдена.

rfind(sub [, start [, end]]) Возвращает наибольший индекс в исходной строке s начала вхождения подстроки sub в s[start:end]. Необязательные аргументы start и end интерпретиру ются так же, как и в операции среза (раздел 11.2). Если подстрока не найдена, возвращает -1.

rindex(sub [, start [, end]]) Аналог метода rfind(), генерирующий исключение, если подстрока не найдена.

startswith(prefix [, start [, end]]) Возвращает 1, если строка s[start:end] начинается с prefix, иначе возвра щает 0.

Преобразование символов и фрагментов строк expandtabs([tabsize]) Возвращает копию исходной строки, в которой все символы табуляции заменены одним или несколькими пробелами в зависимости от текущей позиции размера табуляции. По умолчанию размер табуляции tabsize равен 8 символам.

lstrip() Возвращает копию строки, с удаленными идущими в начале строки символами пропуска (см. метод isspace()).

replace(old, new [, maxcount]) Возвращает копию строки, в которой все вхождения подстроки old заменены на new. Если задан необязательный аргумент maxcount, заменяются только первые maxcount вхождений.

rstrip() Возвращает копию строки, с удаленными идущими в конце строки символами про пуска (см. метод isspace()).

strip() Возвращает копию строки, с удаленными идущими в начале и конце строки сим волами пропуска (см. метод isspace()).

142 Глава 11. Встроенные типы данных translate(table [, delchars]) Возвращает копию строки, в которой все символы, указанные в строке delchars удалены, а для оставшихся символов произведена заменена c table[ord(c)].

Аргумент table должен быть строкой из 256 символов. Замечание: у объектов unicode этот метод имеет другой синтаксис (см. раздел 11.2.2).

encode([encoding [, errors]]) Возвращает представление строки в кодировке encoding (по умолчанию ASCII).

Аргумент errors (строка) указывает способ обработки ошибок. По умолчанию используется ’strict’ — если символ не может быть представлен в дан ной кодировке, генерируется исключение UnicodeError (класс, производный от ValueError). Другие возможные значения — ’ignore’ (отсутствующие в ко дировке символы удаляются) и ’replace’ (отсутствующие в кодировке символы заменяются, обычно на символ ‘?’). (Метод encode() в версии 1.6 определен только для строк Unicode.) Разбиение и объединение join(seq) Возвращает объединение строк-элементов последовательности seq, используя строку s в качестве разделителя. Если последовательность содержит элементы, которые не являются строками, генерирует исключение ValueError.

split([sep [, maxcount]]) Возвращает список слов, содержащихся в исходной строке. В качестве раздели теля слов используется строка sep, если она не задана или равна None, раз делителем слов считаются символы пропуска. Если задан аргумент maxcount и maxcount >= 0, возвращается список из maxcount первых слов и остатка (таким образом список будет содержать не более maxcount-1 элементов).

splitlines([keepends]) Аналог метода split(), использующий в качестве разделителя переход на новую строку. Символы перехода на новую строку включаются в результат, только если задан и является истинным необязательный аргумент keepends.

Методы, зависящие от национальных установок Поведение следующих методов зависит от текущих национальных установок. Вы можете изменить их с помощью функции locale.setlocale() (см. описание стан дартного модуля locale). Применительно к строкам Unicode все описанные здесь мето ды работают со всеми символами Unicode, для которых соответствующее преобразование однозначно.

capitalize() Возвращает копию строки, в которой первая буква заменена на прописную.

11.2. Последовательности isdigit() Возвращает 1, если строка содержит только цифры, иначе возвращает 0.

islower() Возвращает 1, если строка содержит хотя бы один символ, который может быть записан в верхнем и нижнем регистре, и все такие символы в строке находятся в нижнем регистре (строчные), иначе возвращает 0.

isspace() Возвращает 1, если строка содержит только символы пропуска (whitespace) — пробел, табуляция, перевод на новую строку и т. д., иначе возвращает 0.

istitle() Возвращает 1, если регистр букв в строке соответствует заголовку (строчные бук вы следуют только после символов, которые могут быть записаны в верхнем и нижнем регистре, а прописные только после символов, для которых нет понятия регистра, и с начала строки), иначе возвращает 06.

isupper() Возвращает 1, если строка содержит хотя бы один символ, который может быть записан в верхнем и нижнем регистре, и все такие символы в строке находятся в верхнем регистре (прописные), иначе возвращает 0.

lower() Возвращает копию строки, все символы которой приведены к нижнему регистру.

swapcase() Возвращает копию строки, в которой регистр букв изменен с верхнего на нижний и наоборот.

title() Возвращает копию строки, в которой регистр букв соответствует заголовку (строч ные буквы следуют только после символов, которые могут быть записаны в верхнем и нижнем регистре, а прописные только после символов, для которых нет понятия регистра, и с начала строки)6.

upper() Возвращает копию строки, все символы которой приведены к верхнему регистру.

11.2.2 Строки Unicode Литералы для строк Unicode образуются из строковых литералов (любого вида) при добавлении в начало символа ‘u’ или ‘U’: u’abc’, ur"""abc""" (но не ru’abc’).

Кроме того, литералы строк Unicode могут содержать управляющие последовательности вида ‘\uhhhh’, которые интерпретируются так же, как и ‘\xhh...’, но всегда долж ны содержать ровно четыре шестнадцатеричные цифры, что гораздо удобнее. Обратите Несколько упрощенное правило написания заголовков в некоторых западных языках — каждое слово заголовка начинается с прописной буквы. Обычно используется более сложное правило, по которому предлоги пишутся полностью строчными буквами.

144 Глава 11. Встроенные типы данных внимание, что управляющее последовательности вида ‘\xhh...’ и ‘\uhhhh’ позволяют представить все символы Unicode, а ‘\ooo’ — только первые 256.

Синтаксис метода translate объектов unicode отличается от одноименного метода объектов string:

translate(table) Возвращает копию строки, в которой все символы c, для которых в отображении table содержится запись с ключом ord(c), заменены на unichr(table[ord(c)]) или удалены, если table[ord(c)] == None. table может быть отображением любого типа.

Помимо описанных в предыдущем разделе, строки Unicode имеют еще несколько методов:

isdecimal() Возвращает 1, если строка не содержит ничего, кроме десятичных цифр, ина че возвращает 0. Под символами десятичных цифр помимо традиционных ASCII символов подразумеваются также символы, используемые в различных языках, надстрочные и подстрочные десятичные цифры (метод isdigit применительно к строкам Unicode охватывает также и символы с точкой, в скобках, в круге и т. д.).

isnumeric() Возвращает 1, если строка не содержит ничего, кроме символов-чисел, иначе воз вращает 0. Помимо символов цифр, символы чисел включают символы римских чисел, дробные и т. п.

11.2.3 Кортежи Кортежи конструируются простым перечислением элементов через запятую, заключен ным в круглые скобки. Обычно (если это не конфликтует с другими элементами син таксиса языка) скобки можно опустить, однако пустой кортеж всегда должен записы ваться в скобках. Кортеж с одним элементом должен содержать завершающую запятую:

‘a, b, c’, ‘()’, ‘(d,)’. Последовательности другого типа могут быть преобразованы в кортеж с помощью встроенной функции tuple() (см. главу 12). Кортежи не под держивают никаких дополнительных операций кроме тех, которые характерны для всех последовательностей.

11.2.4 Объекты xrange Объект xrange создается встроенной функцией xrange() (см. главу 12) и является псевдопоследовательностью, представляющей ряд целых чисел (объект не хранит свои элементы, а создает каждый элемент при обращении к нему). Достоинство объектов 11.2. Последовательности xrange состоит в том, что они всегда занимают одинаковое количество памяти, неза висимо от размера представляемого диапазона. Использование объектов xrange вместо списков не дает существенного выигрыша в производительности.

Помимо операций, определенных для всех последовательностей, объекты xrange имеют один метод:

tolist() Преобразует объект, к которому метод применяется, в объект-список и возвращает его.

11.2.5 Объекты buffer Объекты buffer создаются с помощь встроенной функции buffer() (см. главу 12) из различных объектов, поддерживающих соответствующий интерфейс: встроенных типов string, unicode, buffer, а также некоторых типов, определенных в различных мо дулях (например, array из модуля array). Объекты buffer позволяют обращаться с различными структурами как с массивами байтов. При этом все изменения в исходный объект будут немедленно отражаться в (ранее созданном) объекте buffer. Встроенная функция str() преобразует объект buffer в строку.

11.2.6 Изменяемые последовательности Все описанные выше последовательности являются неизменяемыми — после созда ния такого объекта Вы не можете внести в него изменения. Объекты-списки (list) поддерживают дополнительные операции, позволяющие изменять объект7. Списки кон струируются путем перечисления в квадратных скобках через запятую его элементов:

‘[a, b, c]’. Начиная с версии 2.0, списки могут быть также сконструированы с помо щью расширенной записи ‘[expression iter_list]’, где iter_list состоит из од ного или нескольких (разделенных символами пропуска) выражений вида ‘for lvalue in expression’ и, возможно, ‘if test’. При этом для каждой комбинации всех lvalue (см. раздел 10.3.2), для которой все выражения test являются истинными.

Ниже приведены дополнительные операции, позволяющие добавлять, удалять и заменять элементы списка (x — произвольный объект, s и t — последовательности одинакового3 типа):

s[i] = x Заменяет элемент последовательности, на который указывает индекс i на x.

del s[i] Удаляет элемент последовательности, на который указывает индекс i.

В дальнейшем, возможно, в язык будут добавлены другие типы изменяемых последовательностей. К ним также будут применимы операции, описанные в этом разделе.

146 Глава 11. Встроенные типы данных s[[i]:[j]] = t Заменяет срез последовательности от i до j на t (удаляет из последовательности элементы входящие в срез и вставляет элементы из t).

del s[[i]:[j]] Удаляет из последовательности элементы, входящие в срез (эквивалентно ‘s[i:j] = []’).

Кроме того, Вы можете вносить изменения в изменяемые последовательности с помощью методов (x — произвольный объект, s — последовательность, к которой при меняется метод, и t — последовательность того же3 типа). Для экономии памяти при работе с большими списками все методы вносят изменения в уже существующий спи сок, а не создают новый. Во избежание возможных ошибок, они (если не указано иного) не возвращают результат.

append(x) Добавляет объект в конец последовательности (для списков это эквивалентно ‘s[len(s):len(s)] = [x]’).

extend(t) Добавляет в конец последовательности элементы последовательности t (эквива лентно ‘s[len(s):len(s)] = x’).

count(x) Возвращает число вхождений элемента x в последовательность (число элементов последовательности s, равных x).

index(x) Возвращает наименьшее i, для которого s[i] == x. Генерирует исключение ValueError, если последовательность не содержит элемента, равного x.

insert(i, x) Вставляет в последовательность элемент x перед i-м элементом (для списков это эквивалентно ‘s[i:i] = [x]’, если i >= 0, иначе элемент вставляется в нача ло). Если значение индекса меньше нуля, элемент вставляется в начало последо вательности, если больше длины последовательности — в ее конец.

pop([i]) Возвращает i-й элемент последовательности, одновременно удаляя его из списка.

Если индекс не указан, подразумевается последний элемент списка. Положение элемента можно отсчитывать с конца, указывая отрицательный индекс. Если ин декс выходит за пределы диапазона, генерируется исключение IndexError.

remove(x) Удаляет из списка первый элемент со значением x (эквивалентно del s[s.index(x)]). Если такового в списке нет, то генерируется исклю чение ValueError.

reverse() Располагает элементы последовательности в обратном порядке.

11.3. Отображения sort([cmpfunc]) Располагает элементы последовательности в порядке возрастания. В качестве необязательного параметра можно передать функцию двух переменных, опреде ляющую сравнение (по умолчанию сравнение производится так же, как и встроен ной функцией cmp()). Однако использование пользовательской функции сравне ния значительно замедляет процесс сортировки. Так, например, последовательное применение методов sort() и reverse() работает значительно быстрее, чем сортировка с использованием функции сравнения ‘lambda x, y: cmp(y, x)’.

11.3 Отображения Отображения ставят в соответствие объектам (ключам) другие объекты. Отображения являются изменяемыми объектами. В настоящее время есть только один стандартный тип отображения — словарь (dictionary). В качестве ключа в словаре не могут ис пользоваться изменяемые объекты, сравнение которых производится по значению вме сто простой проверки идентичности (см. раздел 10.2.4), например списки и словари.

Если два объекта равны (в том числе, если они имеют разный тип), например 1 и 1.0, при использовании их в качестве ключа Вы получите доступ к одной и той же записи словаря.

Создаются словари путем перечисления в фигурных скобках через запя тую пар key: value, например, ‘{’jack’: 4098, ’sjoerd’: 4127}’ или ‘{4098: ’jack’, 4127: ’sjoerd’}’. Интерпретатор не обнаруживает конфлик ты, связанные с наличием нескольких записей с одинаковыми ключами, — сохраняется только запись, идущая последней.

Для отображений определены следующие операции (m — отображение, k — ключ, v — произвольный объект):

len(m) Возвращает количество записей в m.

m[k] Значение, соответствующий ключу k в m. Если отображение не содержит запись с ключом k, генерируется исключение KeyError.

m[k] = v Устанавливает значение, соответствующее ключу k в v.

del m[k] Удаляет из m запись, соответствующую ключу k. Если отображение не содержит запись с ключом k, генерируется исключение KeyError.

Кроме того, отображения имеют следующие методы (m — отображение, к которому применяется метод, n — отображение того же8 типа, k — ключ, v — произвольный объект):

Отображения, определяемые пользователем, могут не иметь этого ограничения.

148 Глава 11. Встроенные типы данных clear() Удаляет все записи из отображения.

copy() Создает и возвращает поверхностную (т. е. ключи и значения нового отображения являются теми же объектами, которые были в исходном, а не их копиями) копию исходного отображения.

has_key(k) Возвращает 1, если отображение содержит запись с ключом k, иначе возвращает 0.

items() Возвращает список записей отображения в виде ‘(key, value)’ keys() Возвращает список ключей отображения.

update(m) Эквивалентно выполнению ‘for k in b.keys(): m[k] = b[k]’.

values() Возвращает список значений, содержащихся в отображении.

get(k [, v]) Возвращает m[k], если отображение содержит запись с ключом k, иначе v (по умолчанию None).

Pages:     | 1 || 3 | 4 |   ...   | 7 |



© 2011 www.dissers.ru - «Бесплатная электронная библиотека»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 1-2 рабочих дней удалим его.