Главная страница

справочник по Python. мм isbn 9785932861578 9 785932 861578


Скачать 4.21 Mb.
Названиемм isbn 9785932861578 9 785932 861578
Анкорсправочник по Python
Дата08.05.2022
Размер4.21 Mb.
Формат файлаpdf
Имя файлаBizli_Python-Podrobnyy-spravochnik.440222.pdf
ТипСправочник
#518195
страница8 из 82
1   ...   4   5   6   7   8   9   10   11   ...   82

class Foo(object):
...
pass
...
>>> type(Foo)

В следующей таблице приводятся атрибуты объекта t типа type, используе- мые чаще всего:
Атрибут
Описание
t.__doc__
Строка документирования
t.__name__
Имя класса
t.__bases__
Кортеж с базовыми классами
t.__dict__
Словарь, содержащий методы и атрибуты класса
t.__module__
Имя модуля, в котором определен класс
t.__abstractmethods__
Множество имен абстрактных методов (может быть неопределен, если абстрактные методы отсутствуют в классе)
Когда создается экземпляр класса, типом объекта становится класс, опре- деляющий его. Например:
>>> f = Foo()
>>> type(f)

В следующей таблице перечислены специальные атрибуты экземпляра i:
Атрибут
Описание
i.__class__
Класс, которому принадлежит экземпляр
i.__dict__
Словарь, содержащий данные экземпляра
Атрибут __dict__ обычно служит для хранения данных, ассоциирован- обычно служит для хранения данных, ассоциирован- служит для хранения данных, ассоциирован- служит для хранения данных, ассоциирован- для хранения данных, ассоциирован- для хранения данных, ассоциирован- хранения данных, ассоциирован- хранения данных, ассоциирован- данных, ассоциирован- данных, ассоциирован-
, ассоциирован- ассоциирован- ных с экземпляром. Когда выполняется операция присваивания, такая как i.attr = value, значение value сохраняется в этом словаре. Однако, если в пользовательском классе определен атрибут __slots__, используется бо- лее эффективное представление экземпляра, и у него уже не будет атрибута
__dict__
. Подробнее об объектах и организации объектной модели в языке
Python рассказывается в главе 7.

80
Глава 3. Типы данных и объекты
Модули
Т
ип модуль – это контейнер, хранящий объекты, загруженные инструкци- ей import. Например, когда в программе встречается инструкция import foo, имя foo связывается с соответствующим объектом модуля. Модули форми- руют свои пространства имен, которые реализуются на основе словарей, доступных в виде атрибута __dict__. Всякий раз, когда выполняется обра- щение к атрибуту модуля (с использованием оператора точки), оно транс- лируется в операцию поиска по словарю. Например, обращение m.x экви- экви- валентно обращению m.__dict__[“x”]. Точно так же присваивание атрибуту модуля, например: m.x = y, эквивалентно присваиванию m.__dict__[“x”] = y.
Модули имеют следующие атрибуты:
Атрибут
Описание
m.__dict__
Словарь, содержащий атрибуты модуля
m.__doc__
Строка документирования модуля
m.__name__
Имя модуля
m.__file__
Имя файла, откуда был загружен модуль
m.__path__
Полное имя пакета. Определен, только когда объ- ект модуля ссылается на пакет
Встроенные типы данных для внутренних
механизмов интерпретатора
Ряд объектов, используемых внутренней реализацией интерпретатора, до- ступен пользователю. В их число входят объекты с трассировочной инфор- мацией, объекты с программным кодом, объекты кадров стека, объекты генераторов, объекты срезов и Ellipsis. Все они перечислены в табл. 3.10.
Эти объекты достаточно редко напрямую используются в программах, но они могут иметь практическую ценность для разработчиков инструментов и фреймворков.
Таблица 3.10. Встроенные типы данных для внутренних механизмов
интерпретатора
Имя типа
Описание
types.CodeType
Скомпилированный байт-код types.FrameType
Кадр стека вызовов types.GeneratorType
Объект генератора types.TracebackType
Трассировочная информация для исключения slice
Создается расширенной операцией получения среза
Ellipsis
Используется расширенной операцией получения среза

Встроенные типы данных для внутренних механизмов интерпретатора
81
Объекты с программным кодом
Объекты с программным кодом представляют скомпилированный, испол- няемый программный код, или байт-код, и обычно создаются встроенной функцией compile(). Эти объекты похожи на функции, за исключением того, что они не содержат контекста, связанного с пространством имен, в котором этот программный код определен, но при этом они хранят инфор- мацию о значениях по умолчанию для аргументов. Объект c с программ- ным кодом имеет следующие атрибуты, доступные только для чтения:
Атрибут
Описание
c.co_name
Имя функции
c.co_argcount
Количество позиционных аргументов (включая значения по умолчанию)
c.co_nlocals
Количество локальных переменных, используемых функ- цией
c.co_varnames
Кортеж с именами локальных переменных
c.co_cellvars
Кортеж с именами переменных, на которые ссылаются вло- женные функции
c.co_freevars
Для вложенных функций. Кортеж с именами свободных переменных, которые определены в объемлющих функциях и используются вложенными функциями
c.co_code
Строковое представление байт-кода
c.co_consts
Кортеж литералов, используемых байт-кодом
c.co_names
Кортеж имен, используемых байт-кодом
c.co_filename
Имя файла, в котором был скомпилирован программный код
c.co_firstlineno
Номер первой строки функции
c.co_lnotab
Строка, представляющая отображение смещений в байт- коде в номера строк
c.co_stacksize
Необходимый размер стека (включая место для локальных переменных)
c.co_flags
Целое число, представляющее различные флаги интерпре- татора. Бит 2 (0x04) устанавливается, если функция прини- мает переменное число позиционных аргументов (
*args
).
Бит 3 (0x08) устанавливается, если функция принимает переменное число именованных аргументов (
**kwds
). Осталь- ные биты не используются и зарезервированы на будущее
Объекты кадра стека
Объекты кадра стека используются для представления окружения выпол- нения и в большинстве случаев создаются объектами с трассировочной ин-

82
Глава 3. Типы данных и объекты формацией (описываются ниже). Объект f кадра стека имеет следующие атрибуты, доступные только для чтения:
Атрибут
Описание
f.f_back
Предыдущий кадр стека (кадр стека вызывающей функции)
f.f_code
Текущий выполняемый объект с программным кодом
f.f_locals
Словарь, используемый для поиска локальных переменных
f.f_globals
Словарь, используемый для поиска глобальных переменных
f.f_builtins
Словарь, используемый для поиска встроенных имен
f.f_lineno
Номер строки
f.f_lasti
Текущая инструкция. Представляет индекс в строке байт-кода объекта f_code
Следующие атрибуты могут изменяться (а также использоваться отладчи- ками и другими инструментами):
Атрибут
Описание
f.f_trace
Функция, которая будет вызываться в начале каждой стро- ки исходного кода
f.f_exc_type
Тип последнего исключения (только в Python 2)
f.f_exc_value
Значение последнего исключения (только в Python 2)
f.f_exc_traceback
Объект с трассировочной информацией последнего исклю- чения (только в Python 2)
Объекты с трассировочной информацией
Объекты с трассировочной информацией создаются в момент появления ис- ключения и содержат информацию о состоянии стека. После входа в блок обработки исключения трассировочную информацию можно получить с помощью функции sys.exc_info(). Объект с трассировочной информацией имеет следующие атрибуты, доступные только для чтения:
Атрибут
Описание
t.tb_next
Ссылка на объект с трассировочной информацией, представ- ляющий следующий уровень (в направлении кадра стека, в ко- тором возникла исключительная ситуация)
t.tb_frame
Ссылка на кадр стека, представляющего текущий уровень
t.tb_lineno
Номер строки, в которой возникла исключительная ситуация
t.tb_lasti
Номер инструкции (на текущем уровне), где возникла исклю- чительная ситуация

Встроенные типы данных для внутренних механизмов интерпретатора
83
Объекты генераторов
Объекты генераторов создаются при вызове функций-генераторов (под- робности приводятся в главе 6 «Функции и функциональное программи- рование»). Функция-генератор создается, если в ней используется специ- альное ключевое слово yield. Объект генератора выступает одновременно в роли итератора и контейнера с информацией о самой функции-генераторе.
Объект генератора обладает следующими атрибутами и методами:
Атрибут
Описание
g.gi_code
Объект с программным кодом функции- генератора
g.gi_frame
Кадр стека функции-генератора
g.gi_running
Целое число, указывающее – выполняется ли функция-генератор в настоящий момент
g.next()
Выполняет функцию-генератор, пока не будет встречена следующая инструкция yield
, и возвращает полученное значение
(в Python 3 этот метод вызывает метод
__next__()
)
g.send(value)
Передает значение value генератору. Это значение возвращается выражением yield в функции-генераторе. После этого функция-генератор продолжит выполне- ние, пока не будет встречена следующая инструкция yield
. Метод send() возвраща- ет значение, полученное от этой инструк- ции yield
g.close()
Закрывает генератор, возбуждая исклю- чение GeneratorExit в функции-генераторе.
Этот метод вызывается автоматически, когда объект генератора уничтожается сборщиком мусора
g.throw(exc [,exc_value [,exc_tb ]])
Возбуждает исключение в функции- генераторе в точке вызова инструкции yield
. exc – тип исключения, exc_value – значение исключения и exc_tb – необяза- тельный объект с трассировочной инфор- мацией. Если исключение перехвачено и обработано, вернет значение, переданное следующей инструкции yield
Объекты срезов
Объекты срезов используются для представления срезов, заданных с при- менением расширенного синтаксиса, например: a[i:j:stride], a[i:j, n:m] или

84
Глава 3. Типы данных и объекты
a[..., i:j]
. Объекты срезов также создаются встроенной функцией slice([i,]
j [,stride])
. Они обладают следующими атрибутами, доступными только для чтения:
Атрибут
Описание
s.start
Нижняя граница среза. Принимает значение None, если не задана.
s.stop
Верхняя граница среза. Принимает значение None, если не задана.
s.step
Шаг среза. Принимает значение None, если не задан.
Объекты срезов также имеют единственный метод s.indices(length). Он принимает длину и возвращает кортеж (start,stop,stride) с параметрами среза для последовательности с указанной длиной. Например:
s = slice(10,20) # Объект среза [10:20]
s.indices(100) # Вернет (10,20,1) —> [10:20]
s.indices(15) # Вернет (10,15,1) —> [10:15]
Объект Ellipsis
Объект Ellipsis используется как признак наличия многоточия (ellipsis) в операторе индексирования []. Существует единственный объект данного типа, доступ к которому осуществляется с помощью встроенного имени El- lipsis
. Он не имеет атрибутов и в логическом контексте оценивается, как значение True. Объект Ellipsis не используется ни в одном из встроенных типов языка Python, но он может быть полезен для тех, кто пожелает рас-
Python, но он может быть полезен для тех, кто пожелает рас-
, но он может быть полезен для тех, кто пожелает рас- ширить функциональность оператора индексирования [] в своих собствен- ных объектах. Ниже демонстрируется, как создается объект Ellipsis и как он передается оператору индексирования:
class Example(object):
def __getitem__(self,index):
print(index)
ёё
e = Example()
e[3, ..., 4] # Вызывает e.__getitem__((3, Ellipsis, 4))
Поведение объектов и специальные методы
Вообще объекты в языке Python классифицируются по их поведению и особенностям, которые они реализуют. Например, все последовательно- сти, такие как строки, списки и кортежи, объединены в одну категорию просто потому, что они поддерживают общий набор операций над последо- вательностями, таких как s[n], len(s) и так далее. Все основные операции интерпретатора реализованы в виде специальных методов объектов. Име- на специальных методов всегда начинаются и оканчиваются двумя симво- лами подчеркивания (__). Эти методы автоматически вызываются интер- претатором в процессе выполнения программы. Например, операция x + y отображается в вызов метода x.__add__(y), а операция доступа к элементу по индексу x[k] отображается в вызов метода x.__getitem__(k). Поведение

Поведение объектов и специальные методы
85
каждого типа данных полностью зависит от набора специальных методов, которые он реализует.
Пользовательские классы могут определять новые объекты, похожие сво- им поведением на встроенные типы, просто реализуя соответствующее подмножество специальных методов, о которых рассказывается в этом раз- деле. Кроме того, за счет переопределения некоторых специальных мето- дов может быть расширена (через наследование) функциональность встро- енных типов, таких как списки и словари.
В следующих нескольких разделах описываются специальные методы, связанные с различными категориями особенностей интерпретатора.
Создание и уничтожение объектов
Методы, перечисленные в табл. 3.11, создают, инициализируют и уничто-
, перечисленные в табл. 3.11, создают, инициализируют и уничто- перечисленные в табл. 3.11, создают, инициализируют и уничто- в табл. 3.11, создают, инициализируют и уничто- в табл. 3.11, создают, инициализируют и уничто- табл. 3.11, создают, инициализируют и уничто- табл. 3.11, создают, инициализируют и уничто-
. 3.11, создают, инициализируют и уничто-
3.11, создают, инициализируют и уничто- жают экземпляры. Метод __new__() – это метод класса, который вызывается для создания экземпляра. Метод __init__() инициализирует атрибуты объ- екта и вызывается сразу же после создания этого объекта. Метод __del__() вызывается перед уничтожением объекта. Вызов этого метода происходит, только когда объект нигде больше не используется. Важно заметить, что инструкция del x всего лишь уменьшает счетчик ссылок на объект и необя- зательно может приводить к вызову этого метода. Подробнее эти методы описываются в главе 7.
Таблица 3.11. Специальные методы создания и уничтожения объектов
Метод
Описание
__new__(
cls [,*args [,**kwargs]])
Метод класса. Вызывается для создания нового экземпляра
__init__(
self [,*args [,**kwargs]])
Вызывается для инициализации нового экземпляра
__del__(
self)
Вызывается перед уничтожением нового экземпляра
Методы __new__() и __init__() используются совместно для создания и ини- циализации новых экземпляров. Когда для создания нового экземпляра производится вызов A(args), он транслируется в следующую последователь- ность действий:
x = A.__new__(A,args)
is isinstance(x,A): x.__init__(args)
В пользовательских объектах редко приходится определять собственные методы __new__() и __del__(). Метод __new__() обычно определяется толь- ко в метаклассах или в пользовательских классах, наследующих один из неизменяемых типов данных (целые числа, строки, кортежи и так далее).
Метод __del__() определяется только в ситуациях, когда необходимо орга- низовать управление некоторыми критически важными ресурсами, на- пример освободить блокировку или закрыть соединение.

86
Глава 3. Типы данных и объекты
Строковое представление объектов
В табл. 3.12 перечислены методы, используемые для создания различных строковых представлений объектов.
Таблица 3.12. Специальные методы для создания представлений
объектов
Метод
Описание
__format__(
self, format_spec)
Создает форматированное строковое представ- ление
__repr__(
self)
Создает строковое представление объекта
__str__(
self)
Создает простое строковое представление объекта
Методы __repr__() и __str__() создают простое строковое представление объекта. Метод __repr__() обычно возвращает строку с выражением, ко- торое может использоваться для воссоздания объекта с помощью функ- ции eval(). Этот метод отвечает также за создание выводимых значений, которые можно наблюдать при инспектировании значений в интерактив- ной оболочке интерпретатора. Этот метод вызывается встроенной функци- ей repr(). Ниже приводится пример совместного использования функций repr()
и eval():
a = [2,3,4,5] # Создание списка s = repr(a) # s = ‘[2, 3, 4, 5]’
b = eval(s) # Строка преобразуется обратно в список
Если по каким-то причинам невозможно создать строковое представле- ние выражения, позволяющего воссоздать объект, по соглашениям метод
__repr__()
должен возвращать строку вида <...сообщение...>, как показано ниже:
f = open(“foo”)
a = repr(f) # a = “
Метод __str__() вызывается встроенной функцией str(), а также функция- ми, отвечающими за вывод информации. Его отличие от метода __repr__() заключается в том, что возвращаемая им строка должна быть более крат- кой и информативной для пользователя. В случае отсутствия этого метода будет вызываться метод __repr__().
Метод __format__() вызывается обычной функцией format() или строковым методом format(). Аргумент format_spec – это строка, содержащая опреде- ление формата. Строка, относительно которой вызывается метод format(), должна иметь тот же вид, что и аргумент format_spec функции format(). На- пример:
format(x,”
spec”) # Вызовет x.__format__(“spec”)
“x is {0:
spec}”.format(x) # Вызовет x.__format__(“spec”)

Поведение объектов и специальные методы
87
Синтаксис спецификаторов формата может быть какой угодно и может из- меняться от объекта к объекту. Однако существует стандартный синтак- сис, который описывается в главе 4.
Сравнение и упорядочение объектов
В табл. 3.13 перечислены методы, которые могут использоваться для вы- табл. 3.13 перечислены методы, которые могут использоваться для вы- табл. 3.13 перечислены методы, которые могут использоваться для вы-
. 3.13 перечислены методы, которые могут использоваться для вы-
3.13 перечислены методы, которые могут использоваться для вы- полнения простейших проверок объектов. Метод __bool__() используется для вычисления признака истинности и должен возвращать True или False.
Если этот метод не определен, для вычисления признака истинности ис- пользуется метод __len__(). Метод __hash__() определяется в объектах, которые должны предоставлять возможность использовать их в качестве ключей словаря. Он должен возвращать одно и то же целое число для объ- ектов, которые при сравнении признаются эквивалентными. Более того, этот метод не должен определяться в изменяемых объектах; любые изме- нения в объекте будут приводить к изменению его хеша, что приведет к не- возможности обнаружения объекта в словаре.
Таблица 3.13. Специальные методы проверки объектов и вычисления их
хешей
Метод
Описание
__bool__(
self)
Возвращает False или True при вычислении значения объекта в логическом контексте
__hash__(
self)
Вычисляет целочисленную хеш-сумму объекта
Объекты могут реализовать поддержку одного или более операторов от- ношений (<, >, <=, >=, ==, !=). Каждый из этих методов принимает два аргу- мента и может возвращать объекты любого типа, включая логический тип
Boolean, список или любой другой тип языка Python. Например, пакет, реализующий численные методы, мог бы использовать эти методы для по- элементного сравнения двух матриц и возвращать матрицу с результатами.
Если сравнение не может быть произведено, эти методы могут возбуждать исключение. Специальные методы, реализующие операторы сравнения, перечислены в табл. 3.14.
Таблица 3.14. Методы, реализующие поддержку операторов сравнения
Метод
Результат
__lt__(
self,other)
self < other
__le__(
self,other)
self <= other
__gt__(
self,other)
self > other
__ge__(
self,other)
self >= other
__eq__(
self,other)
self == other
__ne__(
self,other)
self != other

88
Глава 3. Типы данных и объекты
Объект не обязательно должен реализовывать все методы поддержки опе- раторов сравнения, перечисленные в табл. 3.14. Однако если предполагает-
3.14. Однако если предполагает-
Однако если предполагает- ся, что объект может участвовать в сравнении оператором == или исполь- зоваться в качестве ключа словаря, он должен реализовать метод __eq__().
Если предполагается, что объект может участвовать в операциях сортиров- ки или передаваться таким функциям, как min() и max(), он должен реали- зовывать, по меньшей мере, метод __lt__().
Проверка типа
В табл. 3.15 перечислены методы, которые могут использоваться для пере- определения поведения операций проверки типа, выполняемых функция- ми isinstance() b issubclass(). В большинстве случаев эти методы опреде- ляются в абстрактных базовых классах и интерфейсах, как описывается в главе 7.
Таблица 3.15. Методы проверки типа
Метод
Результат
__instancecheck__(
cls,object)
isinstance
(object, cls)
__subclasscheck__(
cls, sub)
issubclass
(sub, cls)
Доступ к атрибутам
В табл. 3.16 перечислены методы, которые используются для чтения/изме- табл. 3.16 перечислены методы, которые используются для чтения/изме- табл. 3.16 перечислены методы, которые используются для чтения/изме-
. 3.16 перечислены методы, которые используются для чтения/изме-
3.16 перечислены методы, которые используются для чтения/изме- нения и удаления атрибутов объектов оператором точки (.) и инструкцией del соответственно.
Таблица 3.16. Специальные методы доступа к атрибутам
Метод
Описание
__getattribute__(
self,name)
Возвращает атрибут self.name.
__getattr__(
self, name)
Возвращает атрибут self.name, который не может быть найден обычным способом, или возбуждает исключение AttributeError.
__setattr__(
self, name, value)
Изменяет значение атрибута при выполне- нии операции self.name = value. Переопре- деляет механизм присваивания, исполь- зуемый по умолчанию.
__delattr__(
self, name)
Удаляет атрибут self.name.
Метод __getattribute__() вызывается всякий раз, когда производится об- ращение к атрибуту. Если методу удается обнаружить требуемый атрибут, он возвращает его значение. В противном случае вызывается метод __get- attr__()
. По умолчанию метод __getattr__() возбуждает исключение Attrib- uteError
. При присваивании значения атрибуту всегда вызывается метод __
setattr__()
, а при удалении атрибута всегда вызывается метод __delattr__().

Поведение объектов и специальные методы
89
Обертывание атрибутов и дескрипторы
Важным аспектом управления атрибутами является возможность обер- нуть атрибуты объекта дополнительным уровнем логики, которая выпол- няется при вызове операций чтения, изменения и удаления, описанных в предыдущем разделе. Этот вид обертывания обеспечивается за счет соз- дания объекта дескриптора, реализующего один или более методов, пере- численных в табл. 3.17. Следует заметить, что дескрипторы не являются обязательными и необходимость в них на практике возникает достаточно редко.
Таблица 3.17. Специальные методы объектов-дескрипторов
Метод
Описание
__get__(
self,instance,cls)
Возвращает значение атрибута или возбуж- дает исключение AttributeError
__set__(
self,instance,value)
Записывает в атрибут значение value
__delete__(
self,instance)
Удаляет атрибут
Методы __get__(), __set__() и __delete__() дескриптора предназначены для взаимодействия с реализацией по умолчанию методов __getattribute__(),
__setattr__()
и __delattr__() в классах и типах. Такое взаимодействие стано- в классах и типах. Такое взаимодействие стано- классах и типах. Такое взаимодействие стано- классах и типах. Такое взаимодействие стано- и типах. Такое взаимодействие стано- и типах. Такое взаимодействие стано- типах. Такое взаимодействие стано- типах. Такое взаимодействие стано-
. Такое взаимодействие стано-
Такое взаимодействие стано- вится возможным, если поместить экземпляр дескриптора в тело пользова- тельского класса. В этом случае все операции с атрибутом, определенным с помощью дескриптора, неявно будут вызывать соответствующие методы объекта дескриптора. Обычно дескрипторы используются для реализации низкоуровневой функциональности объектно-ориентированных механиз- мов, включая поддержку связанных и несвязанных методов, методов клас- сов, статических методов и свойств. Примеры использования дескрипторов приводятся в главе 7.
Методы последовательностей и отображений
В табл. 3.18 перечислены методы, используемые объектами, имитирующи- ми поведение последовательностей и отображений.
Таблица 3.18. Методы последовательностей и отображений
Метод
Описание
__len__(
self)
Возвращает длину объекта self
__getitem__(
self, key)
Возвращает self[key]
__setitem__(
self, key, value)
Реализует присваивание self[key] = value
__delitem__(
self, key)
Удаляет self[key]
__contains__(
self, obj)
Возвращает True, если obj присутствует в self; в противном случае возвращает False

90
Глава 3. Типы данных и объекты
Примеры:
a = [1,2,3,4,5,6]
len(a) # a.__len__()
x = a[2] # x = a.__getitem__(2)
a[1] = 7 # a.__setitem__(1,7)
del a[2] # a.__delitem__(2)
5 in a # a.__contains__(5)
Метод __len__() вызывается встроенной функцией len() и должен возвра- щать неотрицательное значение длины. Кроме того, в случае отсутствия метода __bool__() этот метод также используется при определении значе- ния истинности объекта.
Для манипулирования отдельными элементами может использоваться ме- тод __getitem__(), который должен возвращать элемент, соответствующий указанному ключу key. В качестве ключа может использоваться любой объект языка Python, но для последовательностей обычно используются целые числа. Метод __setitem__() реализует операцию присваивания зна- реализует операцию присваивания зна- операцию присваивания зна- операцию присваивания зна- присваивания зна- присваивания зна- зна- зна- чения value элементу. Метод __delitem__() вызывается всякий раз, когда вызывается инструкция del для отдельного элемента. Метод __contains__() обеспечивает реализацию оператора in.
Кроме того, с применением методов __getitem__(), __setitem__() и __deli- deli- tem__()
реализуются операции получения срезов, такие как x = s[i:j]. Од- нако в этом случае в качестве ключа передается специальный объект сре- за – slice. Данный объект имеет атрибуты, описывающие параметры за- прошенного среза. Например:
a = [1,2,3,4,5,6]
x = a[1:5] # x = a.__getitem__(slice(1,5,None))
a[1:3] = [10,11,12] # a.__setitem__(slice(1,3,None), [10,11,12])
del a[1:4] # a.__delitem__(slice(1,4,None))
Операции получения среза, реализованные в языке Python, в действитель-
Python, в действитель-
, в действитель- ности обладают более широкими возможностями, чем полагают многие программисты. Например, ниже приводятся поддерживаемые разновид- ности операции получения срезов, которые могут быть полезны при работе с многомерными структурами данных, такими как матрицы и массивы:
a = m[0:100:10] # Срез с шагом (шаг=10)
b = m[1:10, 3:20] # Многомерный срез c = m[0:100:10, 50:75:5] # Многомерный срез с шагом m[0:5, 5:10] = n # Расширенная операция присваивания срезу del m[:10, 15:] # Расширенная операция удаления среза
В общем случае для каждого измерения может применяться своя операция среза в виде i:j[:stride], где значение stride (шаг) является необязательным.
Как и в случае обычных срезов, допускается опускать начальное и конеч- ное значения для каждого измерения. Кроме того, в расширенных опера- циях получения срезов допускается использовать многоточие (записывает- ся как ...) для любого количества начальных и конечных измерений:

Поведение объектов и специальные методы
91
a = m[..., 10:20] # расширенная операция извлечения среза с многоточием m[10:20, ...] = n
При использовании расширенных операций получения срезов реализация чтения, изменения и удаления элементов возлагается на методы __get- get- item__()
, __setitem__() и __delitem__() соответственно. Однако вместо цело- численных значений этим методам передаются кортежи, содержащие ком- бинации параметров срезов и объектов Ellipsis. Например, инструкция a = m[0:10, 0:100:5, ...]
вызовет метод __getitem__():
a = m.__getitem__((slice(0,10,None), slice(0,100,5), Ellipsis))
Строки, кортежи и списки в языке Python в настоящее время обеспечива-
Python в настоящее время обеспечива- в настоящее время обеспечива- ют некоторую поддержку расширенного синтаксиса срезов, который опи- сывается в главе 4. Специальные расширения Python, особенно связанные с научными вычислениями, могут предлагать новые типы и объекты с рас- ширенной поддержкой операций получения срезов.
Итерации
Если объект obj поддерживает итерации, он должен реализовать метод
obj.__iter__()
, возвращающий объект итератора. Объект итератора iter, в свою очередь, должен реализовать единственный метод iter.next() (или
iter.__next__()
в Python 3), возвращающий следующий объект или возбуж-
Python 3), возвращающий следующий объект или возбуж-
3), возвращающий следующий объект или возбуж- дающий исключение StopIteration в конце итераций. Оба эти метода ис- пользуются инструкцией for и другими инструкциями, неявно выполняю- щими итерации. Например, инструкция for x in s выполняет следующие действия:
_iter = s.__iter__()
while 1:
try:
x = _iter.next() # _iter.__next__() в Python 3
except StopIteration:
break
# Инструкции, составляющие тело цикла for
...
Математические операции
В табл. 3.19 перечислены специальные методы объектов, которые имитиру- табл. 3.19 перечислены специальные методы объектов, которые имитиру- табл. 3.19 перечислены специальные методы объектов, которые имитиру-
. 3.19 перечислены специальные методы объектов, которые имитиру-
3.19 перечислены специальные методы объектов, которые имитиру- ют поведение чисел. Математические операции всегда выполняются слева направо, с учетом правил предшествования, описываемых в главе 4; когда в программе встречается выражение, такое как x + y, интерпретатор пыта- ется вызвать метод x.__add__(y). Специальные методы, имена которых на- чинаются с символа r, реализуют поддержку операций, где операнды меня- ются местами. Они вызываются, только если левый операнд не реализует поддержку требуемой операции. Например, если объект x, используемый в выражении x + y, не имеет метода __add__(), интерпретатор попытается вызвать метод y.__radd__(x).

92
Глава 3. Типы данных и объекты
Таблица 3.19. Методы математических операций
Метод
Результат
__add__(
self,other)
self + other
__sub__(
self,other)
self - other
__mul__(
self,other)
self * other
__div__(
self,other)
self / other
(
только в Python 2)
__truediv__(
self,other)
self / other
(Python 3)
__floordiv__(
self,other)
self // other
__mod__(
self,other)
self % other
__divmod__(
self,other)
divmod(
self,other)
__pow__(
self,other [,modulo])
self ** other,pow(self, other, modulo)
__lshift__(
self,other)
self << other
__rshift__(
self,other)
self >> other
__and__(
self,other)
self & other
__or__(
self,other)
self | other
__xor__(
self,other)
self ^ other
__radd__(
self,other)
other + self
__rsub__(
self,other)
other - self
__rmul__(
self,other)
other * self
__rdiv__(
self,other)
other / self
(только в Python 2)
__rtruediv__(
self,other)
other / self
(Python 3)
__rfloordiv__(
self,other)
other // self
__rmod__(
self,other)
other % self
__rdivmod__(
self,other)
divmod(
other,self)
__rpow__(
self,other)
other ** self
__rlshift__(
self,other)
other << self
__rrshift__(
self,other)
other >> self
__rand__(
self,other)
other & self
__ror__(
self,other)
other | self
__rxor__(
self,other)
other ^ self
__iadd__(
self,other)
self += other
__isub__(
self,other)
self -= other
__imul__(
self,other)
self *= other
__idiv__(
self,other)
self /= other
(только в Python 2)
__itruediv__(
self,other)
self /= other
(Python 3)

Поведение объектов и специальные методы
93
Метод
Результат
__ifloordiv__(
self,other)
self //= other
__imod__(
self,other)
self %= other
__ipow__(
self,other)
self **= other
__iand__(
self,other)
self &= other
__ior__(
self,other)
self |= other
__ixor__(
self,other)
self ^= other
__ilshift__(
self,other)
self <<= other
__irshift__(
self,other)
self >>= other
__neg__(
self)

self
__pos__(
self)
+
self
__abs__(
self)
abs(
self)
__invert__(
self)


self
__int__(
self)
int(
self)
__long__(
self)
long(
self)
(
только в Python 2)
__float__(
self)
float(
self)
__complex__(
self)
complex(
self)
Методы __iadd__(), __isub__() и т. д. используются для поддержки арифме- тических операций, сохраняющих результат в одном из операндов, таких как a+=b и a-=b (известных также как комбинированные операции присваи-
вания
). Такое различие между этими операциями и стандартными ариф- метическими методами было введено с целью реализовать возможность по- путного изменения одного из операндов и тем самым обеспечить дополни- тельный прирост скорости выполнения операций. Например, если объект в аргументе self не используется другими объектами, его можно было бы изменить непосредственно, избежав необходимости выделять память для вновь создаваемого объекта с результатом.
Существуют три разновидности операторов деления, __div__(), __truediv__() и __floordiv__(), которые реализуют операции истинного деления (/) и деле- ния с усечением дробной части (//). Наличие трех разновидностей связано с изменением семантики целочисленного деления, появившейся в версии
Python 2.2, которая в Python 3 была утверждена семантикой оператора /, подразумеваемой по умолчанию. В Python 2 оператор / по умолчанию ото- бражается на вызов метода __div__(). Для целых чисел этот метод усекает результат до целого. В Python 3 оператор деления / отображается на вызов метода __truediv__() и даже для целых чисел возвращает значение с плава- ющей точкой. Последнее приведенное поведение может быть реализовано в Python 2 через дополнительную особенность, за счет включения в про-
Python 2 через дополнительную особенность, за счет включения в про-
2 через дополнительную особенность, за счет включения в про- грамму инструкции from __future__ import division.
Методы __int__(), __long__(), __float__() и __complex__() преобразуют объ- ект, выполняя приведение к одному из четырех встроенных числовых ти-

94
Глава 3. Типы данных и объекты пов. Эти методы явно вызываются при выполнении операций приведения типа, таких как int() или float(). Однако эти методы не используются в ма- тематических операциях для неявного приведения типов. Например, вы- ражение 3 + x породит исключение TypeError, даже если пользовательский объект x будет иметь реализацию метода __int__() для преобразования его в целое число.
Интерфейс вызываемых объектов
Объект может имитировать поведение функции, предоставляя метод __
call__(
self [,*args [, **kwargs]])
. Если объект x предоставляет этот метод, к нему можно обратиться, как к функции. То есть инструкция x(arg1, arg2,
...)
вызовет метод x.__call__(self, arg1, arg2, ...). Объекты, имитирующие поведение функции, удобно использовать для создания функторов или прокси-объектов. Ниже приводится простой пример:
class DistanceFrom(object):
def __init__(self,origin):
self.origin = origin def __call__(self, x):
return abs(x - self.origin)
ёё
nums = [1, 37, 42, 101, 13, 9, -20]
nums.sort(key=DistanceFrom(10)) # Отсортирует по степени близости к числу 10
В этом примере создается экземпляр класса DistanceFrom, который имити- рует поведение функции с одним аргументом. Он может использоваться вместо обычной функции – например, в вызове функции sort(), как в дан- ном примере.
Протокол управления контекстом
Инструкция with позволяет организовать выполнение последовательности инструкций под управлением другого объекта, известного как менеджер
контекста
. В общем виде эта инструкция имеет следующий синтаксис:
with
context [ as var]:
инструкции
Ожидается, что объект context реализует методы, перечисленные в табл. 3.20.
Метод __enter__() вызывается при выполнении инструкции with. Значение, возвращаемое этим методом, помещается в переменную, определенную с помощью необязательного спецификатора as var. Метод __exit__() вы- зывается, как только поток выполнения покидает блок инструкций, ассо- циированный с инструкцией with. В качестве аргументов методу __exit__() передаются тип исключения, его значение и объект с трассировочной ин- формацией, если в процессе выполнения инструкций в блоке было воз- буждено исключение. В случае отсутствия ошибок во всех трех аргументах передается значение None.

Поведение объектов и специальные методы
95
Таблица 3.20. Специальные методы менеджеров контекста
Метод
Описание
__enter__(
self)
Вызывается при входе в новый контекстный блок. Возвращаемое значение помещается в переменную, указанную в спецификаторе as инструкции with
__exit__(
self, type, value, tb)
Вызывается, когда поток выполнения покида- ет контекстный блок. Если в процессе выпол- нения инструкций в блоке было возбуждено исключение, в аргументах type, value и tb пере- даются тип исключения, его значение и объ- ект с трассировочной информацией. В первую очередь инструкция with предназначена для упрощения управления системными ресур- сами, такими как открытые файлы, сетевые соединения и блокировки. Благодаря реализа- ции этого интерфейса объект может безопасно освобождать ресурсы после выхода потока выполнения за пределы контекста, в котором этот объект используется. Дополнительное описании приводится в главе 5 «Структура программы и управление потоком выполне- ния».
Функция dir() и инспектирование объектов
Функция dir() часто используется для инспектирования объектов. Объект может сам генерировать список имен, возвращаемый функцией dir(), если реализует метод __dir__(self). С помощью этого метода можно скрыть вну- тренние особенности объекта, о которых нежелательно было бы сообщать пользователю. Однако не забывайте, что пользователь может получить полный перечень определенных имен, прибегнув к исследованию атрибута
__dict__
экземпляров и классов.

1   ...   4   5   6   7   8   9   10   11   ...   82


написать администратору сайта