Марк Лутц - Изучаем Python, Четвертое издание (1184811), страница 80
Текст из файла (страница 80)
Для списков всегда можно создать поверхностную копию с помощью операции извлечения среза с незаданными пределами:>>> L = [1, 2, 3]>>> M = [‘X’, L[:], ‘Y’]>>> L[1] = 0>>> L[1, 0, 3]>>> M[‘X’, [1, 2, 3], ‘Y’]# Встраивается копия L# Изменяется только L, но не MНе забывайте, что значениями пределов по умолчанию являются 0 и длина последовательности, откуда извлекается срез. Если оба значения опущены, в результате операции будут извлечены все элементы последовательности, что создаст поверхностную копию (новый, не разделяемый ни с кем, объект).314Глава 9.
Кортежи, файлы и все остальноеОперация повторения добавляетодин уровень вложенностиОперация повторения последовательности добавляет последовательность самук себе заданное число раз. Это правда, но когда появляются вложенные изменяемые последовательности, эффект может не всегда получиться таким, каквы ожидаете. Например, в следующем примере переменной X присваиваетсясписок L, повторенный четырежды, тогда как переменной Y присваивается повторенный четырежды список, содержащий L:>>> L = [4, 5, 6]>>> X = L * 4# Все равно, что [4, 5, 6] + [4, 5, 6] + ...>>> Y = [L] * 4# [L] + [L] + ... = [L, L,...]>>> X[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]>>> Y[[4, 5, 6], [4, 5, 6], [4, 5, 6], [4, 5, 6]]Так как во второй операции повторения L является вложенным списком, то в Yпопадают ссылки на оригинальный список, связанный с именем L, вследствиечего начинают проявляться те же побочные эффекты, о которых говорилосьв предыдущем разделе:>>> L[1] = 0# Воздействует на Y, но не на X>>> X[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]>>> Y[[4, 0, 6], [4, 0, 6], [4, 0, 6], [4, 0, 6]]Здесь можно применить то же решение, что и в предыдущем разделе, так какэто в действительности всего лишь другой способ получить разделяемые ссылки на изменяемый объект.
Если вы помните, операции повторения, конкатенации и извлечения среза создают только поверхностные копии объектов, чточаще всего и бывает необходимо.Избегайте создания циклических структур данныхНа самом деле мы уже сталкивались с этим понятием в предыдущем упражнении: если объект-коллекция содержит ссылку на себя, он называется циклическим объектом. Всякий раз, когда интерпретатор Python обнаруживаетциклическую ссылку, он выводит [...], чтобы не попасть в бесконечный цикл:>>> L = [‘grail’]>>> L.append(L)>>> L[‘grail’, [...]]# Добавление ссылки на самого себя# Создает циклический объект: [...]Кроме понимания того, что три точки в квадратных скобках означают циклическую ссылку в объекте, это случай заслуживает особого внимания, т.к. онможет привести к сбоям – циклические структуры могут вызывать неожиданное зацикливание программного кода, если вы не все предусмотрели.
Например, некоторые программы хранят список или словарь уже посещенныхэлементов, с помощью которого обнаруживают попадание в цикл. Советы поустранению этих неполадок приводятся в упражнениях к первой части книги,315В заключениев главе 3; кроме того, решение проблемы приводится также в конце главы 24,в программе reloadall.py.Не создавайте циклические ссылки, если они действительно не нужны. Иногдабывают серьезные основания для создания циклических ссылок, но если вашпрограммный код не предусматривает их обработку, вам не следует слишкомчасто заставлять свои объекты ссылаться на самих себя.Неизменяемые типы не могут изменятьсянепосредственноНаконец, вы не можете изменять неизменяемые объекты непосредственно.Вместо этого создайте новый объект – с помощью операций извлечения среза,конкатенации и так далее, и присвойте, если это необходимо, первоначальнойпеременной:T = (1, 2, 3)T[2] = 4# Ошибка!T = T[:2] + (4,) # Все в порядке: (1, 2, 4)Это может показаться лишней работой, но выигрыш в том, что неизменяемыеобъекты, такие как кортежи и строки, не порождают приведенных выше проблем, т.к.
они не могут изменяться непосредственно и не подвержены, как списки, побочным эффектам такого рода.В заключениеВ этой главе были исследованы последние два базовых типа объектов – кортежи и файлы. Мы узнали, что кортежи поддерживают все операции, обычныедля последовательностей, но не имеют методов и не позволяют выполнять изменения непосредственно в объекте, потому что они относятся к категории неизменяемых объектов.
Мы также узнали, что объекты-файлы возвращаютсяфункцией open и предоставляют методы чтения и записи данных. Мы исследовали проблему преобразования объектов Python в строку и обратно, чтобыиметь возможность сохранять их в файле, и познакомились с модулями pickleи struct, реализующими дополнительные возможности (сериализация объектов и работа с двоичными данными). В заключение мы рассмотрели некоторые свойства, общие для всех типов объектов (например, разделяемые ссылки), и прошлись по списку часто встречающихся ошибок (ловушек), связанныхс типами объектов.В следующей части мы обратимся к теме синтаксиса инструкций в языкеPython – здесь мы исследуем все основные процедурные инструкции.
Следующая глава открывает эту часть книги с введения в общую синтаксическуюмодель языка Python, которая применима ко всем типам операторов. Однако прежде чем двинуться дальше, ознакомьтесь с контрольными вопросамик главе, а затем проработайте упражнения к этой части, чтобы коротко повторить основные понятия. Операторы в основном всего лишь создают и обрабатывают объекты, поэтому прежде чем продолжать чтение, вам необходимопроверить владение этой темой, выполнив упражнения.316Глава 9. Кортежи, файлы и все остальноеЗакрепление пройденногоКонтрольные вопросы1. Как определить размер кортежа? Почему этот инструмент стоит обособленно?2.
Напишите выражение, которое изменит первый элемент в кортеже. Кортежсо значением (4,5,6) должен стать кортежем со значением (1,5,6).3. Какое значение используется по умолчанию в аргументе режима обработкифайла в функции open?4. Каким модулем можно воспользоваться для сохранения объектов Pythonв файл, чтобы избежать выполнения преобразований объектов в строкивручную?5. Как можно выполнить копирование всех частей вложенной структурыв одной инструкции?6. В каких случаях интерпретатор рассматривает объект как «истину»?7. В чем состоит ваша цель?Ответы1. Встроенная функция len возвращает длину (количество содержащихся элементов) любого контейнерного объекта, включая и кортежи. Это – встроенная функция, а не метод, и потому может применяться к самым разнымтипам объектов.
Вообще говоря, встроенные функции и операторы выражений зачастую могут применяться к объектам самых разных типов; методы являются более узкоспециализированными инструментами, которыемогут применяться только к объектам одного типа, однако некоторые типымогут иметь одноименные методы (например, методом index обладают списки и кортежи).2. Поскольку кортежи являются неизменяемыми, в действительности ихнельзя изменить непосредственно, но можно создать новый кортеж с желаемым значением.
Первый элемент заданного кортежа T = (4,5,6) можноизменить, создав новый по частям с помощью операций извлечения срезаи конкатенации: T = (1,) + T[1:]. (Не забывайте, что в кортежах из одного элемента обязательно должна присутствовать завершающая запятая.) Такжеможно было бы преобразовать кортеж в список, выполнить необходимое изменение непосредственно в списке и произвести обратное преобразованиев кортеж, но это более дорогостоящая последовательность действий, которая редко используется на практике; просто используйте списки, если заранее известно, что может потребоваться изменить объект непосредственно.3.
Аргумент режима открытия файла в функции open по умолчанию имеетзначение ‘r’, то есть файл открывается для чтения в текстовом режиме. Чтобы открыть текстовый файл для чтения, достаточно передать функции однотолько имя файла.4. Для сохранения объектов Python в файле можно воспользоваться модулемpickle, что устранит необходимость явного преобразования объектов в строки. Модуль struct позволяет выполнять похожие действия, но в предположении, что данные хранятся в файле в упакованном двоичном формате.Закрепление пройденного3175.
Чтобы скопировать все вложенные части структуры X, можно импортировать модуль copy и вызвать функцию copy.deepcopy(X). Однако такой способредко можно встретить на практике – ссылок обычно бывает достаточно и,как правило, в большинстве случаев достаточно бывает создать поверхностную копию (например, aList[:], aDict.copy()).6.
Объект рассматривается как «истина», если он является либо ненулевымчислом, либо непустым объектом коллекции. Встроенные слова True и Falseпо сути являются предопределенными именами числовых значений 1 и 0 соответственно.7. В число допустимых ответов входят «Изучить язык Python», «Перейтик следующей части книги» или «Найти святую чашу Грааля».Упражнения ко второй частиВ этом разделе вам предлагается снова пройтись по основам встроенных объектов. Как и прежде, вам попутно могут встретиться новые понятия, поэтомуобязательно сверьтесь с ответами в приложении B, когда закончите (и дажеесли еще не закончили).Если у вас не так много свободного времени, я рекомендую начать с упражнений 10 и 11 (так как они наиболее практичные), а затем, когда появится время,пройти все упражнения от первого до последнего.