Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

[ Россум, Дрейк, Откидач ] Язык программирования Python

.pdf
Скачиваний:
282
Добавлен:
25.04.2014
Размер:
1.5 Mб
Скачать

18.5. bisect — поддержание последовательностей в . . .

251

choice(seq)

Выбирает случайный элемент из непустой последовательности seq и возвращает его.

При импортировании модуль whrandom создает экземпляр класса whrandom и

делает его методы seed(), random(), uniform(), randrange(), randint() и choice() доступными в глобальном пространстве имен модуля. Заметим, что использование отдельных экземпляров класса whrandom приведет к использованию независимых последовательностей псевдослучайных чисел.

Методы экземпляров whrandom дают случайные числа с равномерным распределением. Если Вам необходимо получить случайные числа с другими распределениями, воспользуйтесь функциями, определенными в модуле random.

18.5bisect — поддержание последовательностей в сортированном состоянии

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

Модуль bisect предоставляет следующие функции:

bisect(list, item [, lo [, hi]])

Находит место в списке (индекс), в которое необходимо вставить item, для того, чтобы сохранить список в сортированном состоянии. Аргументы lo и hi могут быть использованы для указания подмножества списка, которое следует принимать в рассмотрение. Возвращаемое значения подходит для использования в качестве первого аргумента метода list.insert().

insort(list, item [, lo [, hi]])

Вставляет item в список list, сохраняя сортированное состояние списка. Эквивалентно ‘list.insert(bisect.bisect(list, item, lo, hi), item)’.

Функция bisect() может быть полезна для распределения данных по категориям. В следующем примере эта функция используется для определения оценки (обозначаемой буквой, как это принято во многих западных странах) за экзамен по общему количеству набранных баллов. Пусть 85 и более баллов соответствует оценке ‘A’, 75–84 — ‘B’

ит. д.:

>>>grades = "FEDCBA"

>>>breakpoints = [30, 44, 66, 75, 85]

252

Глава 18. Математический аппарат

>>>from bisect import bisect

>>>def grade(total):

...

return grades[bisect(breakpoints, total)]

...

 

>>>grade(66)

’C’

>>>map(grade, [33, 99, 77, 44, 12, 88]) [’E’, ’A’, ’B’, ’D’, ’F’, ’A’]

18.6array — эффективные массивы чисел

Этот модуль определяет новый тип объектов array, эффективно реализующий массивы значений основных типов: символов, целых и вещественных чисел. Массивы ведут себя аналогично спискам с одним исключением: все сохраняемые в массиве объекты должны быть одного определенного типа. Тип элементов определяется при создании массива одним из следующих символов, идентифицирующих тип:

Символ

Тип языка C

Минимальный размер в

 

 

байтах

 

 

 

’c’

char (символ)

1

’b’

signed char (знаковое целое)

1

’B’

unsigned char (беззнаковое целое)

1

’h’

signed short (знаковое целое)

2

’H’

unsigned short (беззнаковое целое)

2

’i’

signed int (знаковое целое)

2

’I’

unsigned int (беззнаковое целое)

2

’l’

signed long (знаковое целое)

4

’L’

unsigned long (беззнаковое целое)

4

’f’

float (вещественное число)

4

’d’

double (вещественное число)

8

Реальное представление значений зависит от архитектуры машины. Используемый размер доступен через атрибут itemsize массивов. При извлечении элементов из массивов, при конструировании которых использовался символ ’L’ или ’I’, значение представляется типом long int языка Python, так как в рамках типа int не может быть представлен весь диапазон чисел типов unsigned int и unsigned long.

array(typecode [, initializer])

Создает новый объект-массив, тип элементов которого определяется символом typecode, инициализирует элементами последовательности initializer (должен быть списком или обычной строкой; initializer передается методу fromlist() или fromstring()) и возвращает его.

18.6. array — эффективные массивы чисел

253

ArrayType

Объект типа, соответствующий объектам, которые возвращает функция array().

Массивы имеют следующие атрибуты данных и методы:

typecode

Символ, определяющий тип элементов массива.

itemsize

Размер в байтах внутреннего представления одного элемента массива.

append(x)

Добавляет x в конец массива.

buffer_info()

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

byteswap()

Изменяет порядок следования байтов для всех элементов массива. Эта операция может быть выполнена только для значений, внутреннее представление которых имеет размер 1, 2, 4 или 8 байт. Метод может быть полезен при чтении данных из файла, который был записан на машине с другим порядком следования байтов.

count(x)

Возвращает число элементов массива равных x.

extend(a)

Добавляет элементы массива a в конец массива.

fromfile(f, n)

read(f, n)

Считывает и добавляет в конец массива n элементов (машинное представление) из файла, представленного файловым объектом (встроенного типа file) f. Если файл содержит меньше элементов, чем n, генерируется исключение EOFError, но все прочитанные к этому времени элементы добавляются в массив.

Имя read() присутствует для совместимости со старыми версиями.

fromlist(list)

Добавляет в конец массива элементы из списка list. Это эквивалентно инструкции ‘for x in list: a.append(x)’ с одним исключением: если список содержит элементы неверного типа, массив остается без изменений.

fromstring(s)

Добавляет в конец массива элементы из строки s, интерпретируя строку как машинное представление значений (то есть аналогично тому, как это делает метод fromfile()). Число символов в строке должно быть кратным размеру элементов массива.

254

Глава 18. Математический аппарат

index(x)

Возвращает индекс первого элемента массива равного x. Если массив не содержит таких значений, генерируется исключение ValueError.

insert(i, x)

Вставляет значение x в массив перед элементом с индексом i.

pop([i])

Удаляет из массива элемент с индексом i и возвращает его. Использование отрицательных индексов позволяет вести отсчет с конца. По умолчанию аргумент i равен -1, то есть соответствует последнему элементу.

remove(x)

Удаляет из массива первый элемент равный x.

reverse()

Меняет порядок следования элементов массива на обратный.

tofile(f)

write()

Записывает все элементы массива (машинное представление) в файл, представленный файловым объектом f. Имя write() присутствует для совместимости со старыми версиями.

tolist()

Возвращает список элементов массива.

tostring()

Возвращает строку с машинным представлением элементов массива (та же самая последовательность байтов, которая записывается в файл методом tofile()).

255

Глава 19

Интерфейсные классы к встроенным типам

Модули, описанные в этой главе, позволяют определять новые классы, наследующие возможности встроенных типов.

UserString Интерфейсный класс для создания строковых объектов.

UserList Интерфейсный класс для создания последовательностей.

UserDict Интерфейсный класс для создания отображений.

19.1UserString — интерфейсный класс для создания строковых объектов

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

UserString([initialdata])

Возвращает экземпляр класса, который ведет себя аналогично объектам встроенного типа string (обычная строка) или unicode (строка Unicode). Экземпляр инициализируется из initialdata (объект произвольного типа). Если initialdata не является строкой (string или unicode), экземпляр инициализируется строковым представлением объекта (str(initialdata)). Если аргумент initialdata опущен, экземпляр инициализируется пустой строкой. Данные из initialdata сохраняются в виде строки в атрибуте data созданного экземпляра.

В дополнение к методам и операциям, характерным для строк (см. раздел 11.2.1), экземпляры класса UserString имеют следующий атрибут:

data

Строка (string или unicode), в которой хранятся данные.

256

Глава 19. Интерфейсные классы к встроенным типам

В качестве примера класса, производного от UserString модуль определяет еще один класс:

MutableString([initialdata])

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

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

__hash__().

Помимо унаследованных от UserString, экземпляры класса MutableString поддерживают операции, позволяющие изменить объект: изменение и удаление символа (элемента последовательности) и подстроки (среза последовательности) — часть операций, характерных для изменяемых последовательностей (см. раздел 11.2.6).

19.2UserList — интерфейсный класс для создания последовательностей

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

Модуль определяет единственное имя — класс UserList:

UserList([initialdata])

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

В дополнение к методам и операциям, характерным для всех изменяемых последовательностей (см. раздел 11.2.6), экземпляры класса UserList имеют следующий атрибут:

data

Список, в котором хранятся данные.

19.3. UserDict — интерфейсный класс для создания отображений

257

19.3UserDict — интерфейсный класс для создания отображений

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

Модуль определяет единственное имя — класс UserDict:

UserDict([initialdata])

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

В дополнение к методам и операциям, характерным для всех отображений (см. раздел 11.3), экземпляры класса UserDict имеют следующий атрибут:

data

Словарь, в котором хранятся данные.

258

Глава 20

Сохранение и копирование объектов

Модули, описанные в этой главе, предоставляют возможность сохранения и копирования объектов языка Python.

pickle Преобразует объекты языка Python в последовательность байтов и обратно.

cPickle Более быстрый вариант модуля pickle.

shelve Сохранение объектов в базе данных в стиле DBM.

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

struct Преобразование объектов в структуры языка C.

20.1pickle и cPickle — представление объектов в виде последовательности байтов

Модуль pickle реализует простой, но мощный алгоритм “консервирования” (pickling, преобразования объектов в последовательность байтов) почти любых объектов языка Python с возможностью дальнейшего восстановления (unpickling). Однако этот модуль не заботится о сохранении имен объектов и не обеспечивает к ним совместный доступ. Полученную последовательность байтов Вы можете записать в файле, сохранить в базе данных или переслать по сети на другую машину. Модуль shelve предоставляет простой интерфейс для сохранения “законсервированных” объектов в базе данных в стиле DBM.

В то время как реализованный на языке Python модуль pickle работает достаточно медленно, реализованный на C модуль cPickle работает иногда почти в 1000 раз быстрее. Модуль cPickle использует точно такой же алгоритм и имеет аналогичный интерфейс, за исключением того, что вместо классов Pickler и Unpickler используются функции, возвращающие объекты с аналогичным интерфейсом.

Хотя модули pickle и cPickle и используют внутри себя встроенный модуль marshal, они отличаются от этого модуля способом обработки данных:

20.1. pickle и cPickle — представление объектов в виде . . .

259

Модули pickle и cPickle отслеживают объекты, которые уже были обработаны, и никогда не обрабатывают их повторно. Это позволяет “консервировать” рекурсивные объекты (объекты, содержащие ссылки на себя), которые не могут быть обработаны модулем marshal. Аналогично обрабатываются совместно используемые объекты (различные объекты ссылаются на один и тот же объект): они остаются совместно используемыми, что очень важно для изменяемых объектов.

Модуль marshal совсем не поддерживает экземпляры классов, в то время как модули pickle и cPickle позволяют с ними работать. Определение класса должно находиться в том же модуле, в котором оно было при “консервации” объекта.

Используемый формат данных характерен для языка Python и не имеет ограничений, характерных, например, для стандартного формата XDR (External Data Representation), который не позволяет представить совместное использование объектов. Однако это означает, что программы на других языках не смогут восстановить “законсервированный” объект.

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

и dumps().

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

Для удобства работы с долгоживущими модулями предоставляется поддержка ссылок на объекты, которые не подлежат “консервированию”. Для таких объектов запоминается идентификатор, возвращаемый атрибутом-функцией или методом persistent_id(). Идентификатор может быть произвольной строкой из печатных ASCII символов. Для восстановления объекта по идентификатору необходимо определить атрибут-функцию persistent_load().

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

При восстановлении экземпляра класса его метод __init__() обычно не вызывается. Для того, чтобы он вызывался, класс должен иметь метод __getinitargs__() протокола копирования. Другие методы протокола копирования (см. раздел ??) __getstate__() и __setstate__() используются для сохранения и восстановления состояния объекта.

260

Глава 20. Сохранение и копирование объектов

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

Модули pickle и cPickle определяют следующие конструкторы:

Pickler(file [, bin])

Класс (в модуле pickle) или функция (в модуле cPickle), возвращает объект, реализующий “консервирование”. Аргумент file должен быть файловым объектом, имеющим метод write(). Если задан отличный от нуля аргумент bin (целое число), используется более компактный двоичный формат.

Unpickler(file)

Класс (в модуле pickle) или функция (в модуле cPickle), возвращает объект, реализующий восстановление “законсервированного” объекта. Аргумент file должен быть файловым объектом, имеющим методы read() и readline().

Объекты, возвращаемые конструктором Pickler(), имеют следующие (основные) методы:

dump(object)

“Консервирует” объект object.

persistent_id(object)

Этот метод (функция или любой другой объект, поддерживающий вызов) вызывается для каждого из вложенных объектов. Должен возвращать строку-идентификатор постоянного объекта или None, если объект подлежит консервации. Изначально метод persistent_id() не определен (cPickle) или всегда возвращает None

(pickle).

Объекты, возвращаемые конструктором Unpickler(), имеют методы, предназначенные для выполнения обратных действий:

load()

Восстанавливает и возвращает ранее “законсервированный” объект.

noload() (только в модуле cPickle)

Проходит весь цикл восстановления объекта, но сам объект не создает. Может быть полезен для тестирования persistent_load