Главная страница
Навигация по странице:

  • Сравнения, равенство и истина

  • L1 = [1, (a, 3)]

  • S1 = spam >>> S2 = spam >>> S1 == S2, S1 is S2

  • S1 = a longer string >>> S2 = a longer string >>> S1 == S2, S1 is S2

  • L1 = [1, (a, 3)] >>> L2 = [1, (a, 2)] >>> L1 L2

  • L = [None] * 100 >>>>>> L [None, None, None, None, None, None, None, ... ]Объект Значение

  • Иерархии типов данных в языке Python

  • Ловушки встроенных типов

  • Операция присваивания создает ссылку, а не копию

  • L = [1, 2, 3] >>> M = [X, L, Y]

  • Операция повторения добавляет один уровень вложенности

  • L = [4, 5, 6] >>> X = L * 4

  • L[1] = 0

  • L = [grail]

  • Математический анализ. 3е издание


    Скачать 4.86 Mb.
    Название3е издание
    АнкорМатематический анализ
    Дата04.02.2022
    Размер4.86 Mb.
    Формат файлаpdf
    Имя файлаpython_01.pdf
    ТипДокументы
    #351981
    страница32 из 98
    1   ...   28   29   30   31   32   33   34   35   ...   98
    L = ['a', X[:], 'b'] # Встроенные копии объекта X
    >>> D = {'x':X[:], 'y':2}
    Это меняет картину, представленную на рис. 9.2, – L и D теперь ссыла
    ются на другие списки, отличные от X. Теперь изменения, выполнен
    ные с помощью переменной X, отразятся только на самой переменной
    X
    , но не на L и D; точно так же изменения в L или D никак не будут воз
    действовать на X.
    Одно замечание по поводу копий: выражение извлечения среза с пус
    тыми значениями пределов и метод словаря copy создают поверхност+
    ные
    копии – т. е. они не копируют вложенные структуры данных, да
    же если таковые присутствуют. Если необходима полная копия струк
    туры произвольной глубины вложенности, следует использовать стан
    дартный модуль copy: добавьте инструкцию import copy и вставьте выражение X = copy.deepcopy(Y), которое создаст полную копию объекта

    Сравнения, равенство и истина
    257
    Y
    со сколь угодно большой глубиной вложенности. Эта функция вы
    полняет рекурсивный обход объектов и копирует все составные части.
    Однако такой подход используется намного реже (потому что для это
    го приходится писать дополнительный программный код). Обычно ссылки – это именно то, что нам требуется, в противном случае чаще всего применяются такие способы копирования, как операция извле
    чения среза и метод copy.
    Сравнения, равенство и истина
    Любые объекты языка Python поддерживают операции сравнения:
    проверка на равенство, относительная величина и т. д. Операции срав
    нения в языке Python всегда проверяют все части составных объектов,
    пока результат не станет определенным. В действительности, для вло
    женных объектов интерпретатор Python всегда автоматически выпол
    няет обход структуры данных, чтобы применить операции сравнения
    рекурсивно
    , слева направо и настолько глубоко, насколько это необхо
    димо. Первое найденное различие определяет результат сравнения.
    Например, при сравнении списков автоматически сравниваются все их компоненты:
    >>> L1 = [1, ('a', 3)] # Разные объекты с одинаковыми значениями
    >>> L2 = [1, ('a', 3)]
    >>> L1 == L2, L1 is L2 # Эквивалентны? Это один и тот же объект?
    (True, False)
    В данном случае L1 и L2 ссылаются на совершенно разные списки, но с одинаковым содержимым. Изза природы ссылок в языке Python су
    ществует два способа проверки на равенство:

    Оператор == проверяет равенство значений. Интерпретатор выпол
    няет проверку на равенство, рекурсивно сравнивая все вложенные объекты.

    Оператор is проверяет идентичность объектов. Интерпретатор про
    веряет, являются ли сравниваемые объекты одним и тем же объек
    том (т. е. расположены ли они по одному и тому же адресу в памяти).
    В предыдущем примере L1 и L2 прошли проверку == на равенство (они имеют одинаковое значение, потому что все их компоненты равны), но не прошли проверку is на эквивалентность (они ссылаются на разные объекты и, соответственно, на разные области памяти). Однако, обра
    тите внимание, что происходит при сравнении двух коротких строк:
    >>> S1 = 'spam'
    >>> S2 = 'spam'
    >>> S1 == S2, S1 is S2
    (True, True)
    Здесь у нас также присутствуют два различных объекта, имеющие одинаковые значения: оператор == должна вернуть истину, а оператор

    258
    Глава 9. Кортежи, файлы и все остальное is
    – ложь. Но так как интерпретатор с целью оптимизации кэширует и повторно использует короткие строки, в действительности обе они являются одной и той же строкой 'spam' в памяти, которая совместно используется переменными S1 и S2, поэтому оператор is проверки идентичности возвращает истину. Чтобы получить нормальное пове
    дение, потребуется использовать более длинные строки:
    >>> S1 = 'a longer string'
    >>> S2 = 'a longer string'
    >>> S1 == S2, S1 is S2
    (True, False)
    Разумеется, так как строки являются неизменяемыми, использование механизма кэширования объектов не оказывает отрицательного влия
    ния на ваш программный код – строки нельзя изменить непосредст
    венно независимо от того, сколько переменных ссылаются на них. Ес
    ли результат проверки на идентичность кажется вам обескураживаю
    щим, вернитесь к главе 6, чтобы освежить в памяти концепцию ссы
    лок на объекты.
    Как правило, оператор == – это именно то, что требуется в большинстве случаев проверки равенства; оператор is предназначен для особых случаев. Мы рассмотрим случаи использования этих операторов далее в книге.
    Операторы отношений к вложенным структурам также применяются рекурсивно:
    >>> L1 = [1, ('a', 3)]
    >>> L2 = [1, ('a', 2)]
    >>> L1 < L2, L1 == L2, L1 > L2 # Меньше, равно, больше: кортеж результатов
    (False, False, True)
    Здесь L1 больше, чем L2, потому что вложенное число 3 больше, чем 2.
    Результат последней строки в этом примере в действительности пред
    ставляет собой кортеж из трех объектов – результатов трех выраже
    ний (пример кортежа без объемлющих круглых скобок).
    В общем случае Python сравнивает типы следующим образом:

    Числа сравниваются по величине.

    Строки сравниваются лексикографически, символ за символом
    ("abc" < "ac").

    При сравнении списков и кортежей сравниваются все компоненты слева направо.

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

    Сравнения, равенство и истина
    259
    Смысл понятий «Истина» и «Ложь» в языке Python
    Обратите внимание, что три значения в кортеже, возвращаемом по
    следним примером из предыдущего раздела, – это логические значения
    «истина» (true) и «ложь» (false). Они выводятся на экран как слова True и False, но теперь, когда мы приступаем к использованию логических проверок, мне следует более формально описать смысл этих названий.
    В языке Python, как в большинстве языков программирования, «ложь»
    представлена целочисленным значением 0, а «истина» – целочислен
    ным значением 1. Кроме того, интерпретатор Python распознает лю
    бую пустую структуру данных как «ложь», а любую непустую струк
    тура данных – как «истину». В более широком смысле понятия исти
    ны и лжи – это свойства, присущие всем объектам в Python, – каждый объект может быть либо «истиной», либо «ложью»:

    Числа, отличные от нуля, являются «истиной».

    Другие объекты являются «истиной», если они непустые.
    В табл. 9.4 приводятся примеры истинных и ложных значений объек
    тов в языке Python.
    Таблица 9.4. Примеры значений истинности объектов
    В языке Python имеется также специальный объект с именем None (по
    следняя строка в табл. 9.4), который всегда расценивается как «ложь».
    Объект None был представлен в главе 4 – это единственный специаль
    ный тип данных в языке Python, который играет роль пустого запол
    нителя и во многом похож на указатель NULL в языке C.
    Например, вспомните, что списки не допускают присваивание значе
    ний отсутствующим элементам (списки не вырастают по волшебству,
    когда вы выполняете присваивание некоторого значения несущест
    вующему элементу). Чтобы можно было выполнять присваивание лю
    бому из 100 элементов списка, обычно создается список из 100 элемен
    тов, который заполняется объектами None:
    >>> L = [None] * 100
    >>>
    >>> L
    [None, None, None, None, None, None, None, ... ]
    Объект
    Значение
    "spam"
    True
    ""
    False
    []
    False
    {}
    False
    1
    True
    0.0
    False
    None
    False

    260
    Глава 9. Кортежи, файлы и все остальное
    Логический тип bool в языке Python (представленный в главе 5) просто усиливает понятия «истина» и «ложь» в языке Python. Как вы могли заметить, результаты операций проверок в этой главе выводятся в ви
    де значений True и False. Как мы узнали в главе 5, эти значения явля
    ются всего лишь разновидностями целых чисел 1 и 0. Этот тип реали
    зован так, что он действительно является лишь незначительным рас
    ширением к понятиям «истина» и «ложь», уже описанным, и предна
    значенным для того, чтобы сделать значения истинности более явными. При явном использовании слов True и False в операциях про
    верки на истинность они интерпретируются как «истина» и «ложь»,
    которые в действительности являются специализированными версия
    ми целых чисел 1 и 0. Результаты операций проверок также выводят
    ся как слова True и False, а не как значения 1 и 0.
    Вам необязательно использовать только логические типы в логиче
    ских инструкциях, таких как if, – любые объекты по своей природе могут быть истинными или ложными, и все логические концепции,
    упоминаемые в этой главе, работают, как описано, и с другими типа
    ми. Мы займемся исследованием логического типа, когда будем рас
    сматривать логические инструкции в главе 12.
    Иерархии типов данных в языке Python
    На рис. 9.3 приводятся все встроенные типы объектов, доступные в язы
    ке Python, и отображены взаимоотношения между ними. Наиболее значимые из них мы уже рассмотрели; большая часть других видов объектов на рис. 9.3 соответствует элементам программ (таким как функции и модули) или отражает внутреннее устройство интерпрета
    тора (такие как кадры стека и скомпилированный программный код).
    Главное, что следует учитывать, – в языке Python все элементы явля
    ются объектами и могут быть использованы в ваших программах. На
    пример, можно передать класс в функцию, присвоить его переменной,
    заполнить им список или словарь и т. д.
    Фактически даже сами типы в языке Python являются видом объектов:
    вызов встроенной функции type(X) возвращает тип объекта X. Объекты типов могут использоваться для сравнения типов вручную в инструк
    ции if. Однако по причинам, изложенным в главе 4, ручная проверка типа в языке Python обычно рассматривается как нечто неправильное.
    Одно замечание по поводу имен типов: в версии Python 2.2 у каждого базового типа появилось новое встроенное имя, добавленное для обес
    печения поддержки настройки типов через объектноориентирован
    ный механизм наследования классов: dict, list, str, tuple, int, long,
    float
    , complex, unicode, type и file (file – это синоним для open). Эти имена представляют не просто функции преобразования, а настоящие конструкторы объектов, хотя при решении несложных задач вы може
    те рассматривать их как простые функции.

    Иерархии типов данных в языке Python
    261
    Модуль types, входящий в состав стандартной библиотеки, также пре
    доставляет дополнительные имена типов (по большей части это сино
    нимы встроенных типов) и предоставляет возможность проверять тип объекта с помощью функции isinstance. Например, в Python 2.2 и вы
    ше все следующие операции проверки возвращают истину:
    isinstance([1],list)
    type([1])==list type([1])==type([])
    type([1])==types.ListType
    Поскольку в современных версиях Python от типов можно порождать дочерние классы, рекомендуется не пренебрегать функцией isinstance.
    Подробнее о создании дочерних классов от встроенных типов в версии
    Python 2.2 рассказывается в главе 26.
    Рис. 9.3. Основные встроенные типы в языке Python, организованные
    по категориям. Все в языке Python является объектом, даже сами типы –
    это объекты! Тип любого объекта – это объект типа «type»
    Числа
    Целoе
    Вещественное
    Целые
    Комплексное
    Длинное целое
    Множество
    Логическое
    C фиксированной точностью
    Коллекции
    Последовательности
    Отображения
    Неизменяемые
    Изменяемые
    Строка
    Список
    Словарь
    Юникод
    Кортеж
    Вызываемые
    Функции
    Класс
    Метод
    Связанный
    Несвязанный
    Прочие
    Внутренние
    Модуль
    Тип
    Экземпляр
    Код
    Файл
    Кадр
    Диагностика
    None

    262
    Глава 9. Кортежи, файлы и все остальное
    Другие типы в Python
    Помимо базовых объектов, рассмотренных в этой части книги, в соста
    ве Python обычно устанавливаются десятки других типов объектов,
    доступных в виде связанных расширений на языке C или в виде клас
    сов языка Python – объекты регулярных выражений, файлы DBM,
    компоненты графического интерфейса, сетевые сокеты и т. д.
    Главное отличие между этими и встроенными типами, которые мы до сих пор рассматривали, состоит в том, что для встроенных типов язы
    ком предоставляется специальный синтаксис создания объектов этих типов (например, 4 – для целого числа, [1,2] – для списка и функция open
    – для файла). Другие типы обычно доступны в виде модулей стан
    дартной библиотеки, которые необходимо импортировать перед ис
    пользованием. Например, чтобы создать объект регулярного выраже
    ния, необходимо импортировать модуль re и вызвать re.compile().
    Полное руководство по всем типам, доступным в программах на языке
    Python, вы найдете в справочнике по библиотеке Python.
    Ловушки встроенных типов
    Это окончание нашего обзора базовых типов данных. Мы завершаем эту часть книги обсуждением общих проблем, с которыми сталкива
    ются новые пользователи (а иногда и эксперты), и их решений. Отчас
    ти – это краткий обзор идей, которые мы уже рассматривали, но они достаточно важны, чтобы вновь вернуться к ним.
    Операция присваивания создает ссылку, а не копию
    Поскольку это центральное понятие, я напомню о нем еще раз: вы должны понимать, что может происходить с разделяемыми ссылками в вашей программе. Например, ниже создается объект списка, связан
    ный с именем L, на это имя также ссылается элемент списка M. Таким образом, изменение списка с помощью имени L приведет к изменению списка, на который ссылается и список M:
    >>> L = [1, 2, 3]
    >>> M = ['X', L, 'Y'] # Встраивает ссылку из L
    >>> M
    ['X', [1, 2, 3], 'Y']
    >>> L[1] = 0 # Список M также изменяется
    >>> M
    ['X', [1, 0, 3], 'Y']
    Обычно этот эффект обретает важность только в больших программах,
    и, как правило, совместное использование ссылок – это именно то, что необходимо. Если это является нежелательным, вы всегда можете соз
    дать явно копию объекта. Для списков всегда можно создать поверх

    Ловушки встроенных типов
    263
    ностную копию с помощью операции извлечения среза с незаданными пределами:
    >>> L = [1, 2, 3]
    >>> M = ['X', L[:], 'Y'] # Встраивается копия L
    >>> L[1] = 0 # Изменяется только L, но не M
    >>> L
    [1, 0, 3]
    >>> M
    ['X', [1, 2, 3], 'Y']
    Не забывайте, что значениями пределов по умолчанию являются 0
    и длина последовательности, откуда извлекается срез. Если оба значе
    ния опущены, в результате операции будут извлечены все элементы последовательности, что создаст поверхностную копию (новый, не раз
    деляемый ни с кем объект).
    Операция повторения добавляет
    один уровень вложенности
    Операция повторения последовательности добавляет последователь
    ность саму к себе заданное число раз. Это правда, но когда появляются вложенные изменяемые последовательности, эффект может не всегда получиться таким, как вы ожидаете. Например, в следующем примере переменной 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]]
    Здесь можно применить то же решение, что и в предыдущем разделе,
    так как это в действительности всего лишь другой способ получить разделяемые ссылки на изменяемый объект. Если вы помните, опера
    ции повторения, конкатенации и извлечения среза создают только по
    верхностные копии объектов, что чаще всего и бывает необходимо.

    264
    Глава 9. Кортежи, файлы и все остальное
    Избегайте создания циклических структур данных
    На самом деле мы уже сталкивались с этим понятием в предыдущем упражнении: если объектколлекция содержит ссылку на себя, он на
    зывается циклическим объектом. Всякий раз, когда интерпретатор
    Python обнаруживает циклическую ссылку, он выводит [...], чтобы не попасть в бесконечный цикл:
    >>> L = ['grail'] # Добавление ссылки на самого себя
    >>> L.append(L) # Создает циклический объект: [...]
    >>> L
    ['grail', [...]]
    Кроме понимания того, что три точки в квадратных скобках означают циклическую ссылку в объекте, это случай заслуживает внимания, т. к.
    он может привести к сбоям – циклические структуры могут вызывать неожиданное зацикливание программного кода, если вы не все преду
    смотрели. Например, некоторые программы хранят список или словарь уже посещенных элементов, с помощью которого обнаруживают попа
    дание в цикл. Советы по устранению этих неполадок приводятся в уп
    ражнениях к первой части книги, в главе 3; кроме того, решение про
    блемы приводится также в конце главы 21, в программе reloadall.py.
    Не создавайте циклические ссылки, если они действительно не нуж
    ны. Иногда бывают серьезные основания для создания циклических ссылок, но если ваш программный код не предусматривает их обработ
    ку, вам не следует слишком часто заставлять свои объекты ссылаться на самих себя.
    1   ...   28   29   30   31   32   33   34   35   ...   98


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