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

  • {a: 1, b: 2, c: 3} == {c: 3, a: 1, b: 2}

  • Dunder-методы, или магические методы

  • Вызываемые объекты и первоклассные объекты

  • Частые ошибки при использовании терминов

  • Итерируемые объекты и итераторы

  • Синтаксические ошибки, ошибки времени выполнения

  • Чистыйкод дляпродолжающи х


    Скачать 7.85 Mb.
    НазваниеЧистыйкод дляпродолжающи х
    Дата13.05.2023
    Размер7.85 Mb.
    Формат файлаpdf
    Имя файлаPython_Chisty_kod_dlya_prodolzhayuschikh_2022_El_Sveygart.pdf
    ТипДокументы
    #1127485
    страница15 из 40
    1   ...   11   12   13   14   15   16   17   18   ...   40
    [1, 2, 3] == [3, 2, 1]
    False
    Отображение (mapping) представляет собой объект любого контейнерного типа данных, использующий ключи вместо индексов. Отображение может быть упоря- доченным или неупорядоченным. Словари в Python 3.4 и более ранних версиях не упорядочены, то есть в них не было первой или последней пары «ключ — значение»:
    >>> spam = {'a': 1, 'b': 2, 'c': 3, 'd': 4} # Запускается из CPython 3.5.
    >>> list(spam.keys())
    ['a', 'c', 'd', 'b']
    >>> spam['e'] = 5
    >>> list(spam.keys())
    ['e', 'a', 'c', 'd', 'b']
    В ранних версиях Python постоянный порядок следования элементов в словарях не гарантировался. В результате неупорядоченной природы словарей два словар- ных литерала, записанных с разным порядком пар «ключ — значение», все равно считались равными:
    >>> {'a': 1, 'b': 2, 'c': 3} == {'c': 3, 'a': 1, 'b': 2}
    True
    Но начиная с CPython 3, словари поддерживают порядок вставки своих пар
    «ключ — значение»:

    150
    Глава 7.Жаргон программистов
    >>> spam = {'a': 1, 'b': 2, 'c': 3, 'd': 4} # Запускается из CPython 3.6.
    >>> list(spam)
    ['a', 'b', 'c', 'd']
    >>> spam['e'] = 5
    >>> list(spam)
    ['a', 'b', 'c', 'd', 'e']
    Это особенность интерпретатора CPython 3.6, отсутствующая в других интерпре- таторах Python 3.6. Все интерпретаторы Python 3.7 поддерживают упорядоченные словари, которые стали стандартными для языка Python в версии 3.7. Однако упорядоченность словаря не означает, что к его элементам можно обращаться по целочисленным индексам: spam[0]
    не будет обозначать первый элемент в упоря- доченном словаре (если только по совпадению первый элемент не будет иметь ключ
    0
    ). Упорядоченные словари также считаются равными, если они содержат одинаковые пары «ключ — значение», даже если пары «ключ — значение» в этих словарях следуют в разном порядке.
    Модуль collections содержит много других видов отображений, включая
    Orde- redDict
    ,
    ChainMap
    ,
    Counter и
    UserDict
    . Они описаны в электронной документации по адресу https://docs.python.org/3/library/collections.html.
    Dunder-методы, или магические методы
    Dunder-методы, называемые также магическими, — это специальные методы в Python, которые используются для перезагрузки операторов. Их имена начинают- ся и заканчиваются двумя символами подчеркивания (
    __
    ). (Dunder — сокращение от Double UNDERscore.) Самый известный специальный метод
    __init__()
    ини- циализирует объекты. В Python определено несколько десятков dunder-методов, они подробно рассматриваются в главе 17.
    Модули и пакеты
    Модуль (module) представляет собой программу Python, которая может импорти- роваться другими программами Python, чтобы те могли воспользоваться кодом модуля. Модули, входящие в поставку Python, образуют стандартную библиотеку
    Python, но вы также можете создавать собственные модули. Если сохранить про- грамму Python, например под именем spam.py
    , другие программы смогут выполнить команду import spam
    , чтобы получить доступ к функциям, классам и переменным верхнего уровня программы spam.py
    Пакет (package) представляет собой набор модулей. Чтобы создать его, следует разместить в папке файл с именем
    __init__.py
    . Имя папки становится именем па- кета. Пакеты могут содержать несколько модулей (то есть файлов
    .py
    ) или других пакетов (других папок, содержащих файлы
    __init__.py
    ).

    Определения
    151
    За дополнительными объяснениями и подробностями о модулях и пакетах обра- щайтесь к официальной документации Python по адресу https://docs.python.org/3/
    tutorial/modules.html.
    Вызываемые объекты и первоклассные объекты
    В Python можно вызывать не только функции и методы. Любой объект, реализу- ющий оператор вызова — круглые скобки
    ()
    , называется вызываемым объектом
    (callable). Например, если у вас имеется команда def hello():
    , код можно рассма- тривать как переменную с именем hello
    , содержащую объект функции. При при- менении оператора вызова к этой переменной будет вызвана функция, хранящаяся в переменной: hello()
    Классы относятся к концепциям ООП. Класс является примером вызываемого объ- екта, который не является функцией или методом. Например, класс date в модуле datetime вызывается с использованием оператора вызова, как в примере datetime.
    date(2020,
    1,
    1)
    . При вызове объекта класса выполняется метод
    __init__()
    этого класса. В главе 15 мы поговорим о классах более подробно.
    В Python функции являются первоклассными объектами (first-class objects). Это означает, что их можно сохранять в переменных, передавать в аргументах при вызове функций, возвращать при вызове функций и делать все остальное, что можно сделать с объектом. Рассматривайте команду def как присваивание объекта функции переменной. Например, можно создать функцию spam()
    , которую затем можно вызвать:
    >>> def spam():
    ... print('Spam! Spam! Spam!')
    >>> spam()
    Spam! Spam! Spam!
    Также можно присвоить объект функции spam()
    другим переменным. Когда вы вызываете переменную, которой был присвоен объект функции, Python выполняет эту функцию:
    >>> eggs = spam
    >>> eggs()
    Spam! Spam! Spam!
    Таким образом создаются псевдонимы (aliases) — другие имена для существующих функций. Они часто используются в тех ситуациях, когда возникает необходимость в переименовании функции. Но старое имя используется в большом объеме суще- ствующего кода, и изменение всего этого кода потребовало бы слишком серьезной работы.

    152
    Глава 7.Жаргон программистов
    Первоклассные функции чаще всего используются для передачи функций другим функциям. Например, можно определить функцию callTwice()
    , которая дважды вызывает переданную ей функцию:
    >>> def callTwice(func):
    ... func()
    ... func()
    >>> callTwice(spam)
    Spam! Spam! Spam!
    Spam! Spam! Spam!
    С таким же успехом можно было просто дважды вызвать spam()
    в исходном коде.
    Но функции callTwice()
    можно передать любую функцию во время выполнения, вместо того чтобы заранее включать повторный вызов функции в исходный код.
    Частые ошибки при использовании терминов
    Технический жаргон достаточно неоднозначен — особенно для терминов взаимо- связанных, но имеющих разные определения. Ситуация усугубляется тем, что языки, операционные системы и разные области компьютерной теории могут раз- ными терминами обозначать одни и те же понятия или одинаковыми терминами — разные понятия. Чтобы ясно и однозначно общаться с другими программистами, необходимо понимать различия между терминами, о которых речь пойдет далее.
    Команды и выражения
    Выражениями (expressions) называются инструкции, состоящие из операторов и зна- чений, результатом вычисления которых является одно значение. Таким значением может быть переменная (которая содержит значение) или вызов функции (которая возвращает значение). Таким образом,
    2
    +
    2
    является выражением, при вычислении которого будет получено одно значение
    4
    . С другой стороны, len(myName)
    >
    4
    и myName.
    isupper()
    or myName
    ==
    'Zophie'
    также являются выражениями. Значение само по себе также является выражением, результатом вычисления которого является оно само.
    Практически все остальные инструкции в Python являются командами (statements).
    К их числу относятся команды if
    , команды for
    , команды def
    , команды return и т. д.
    Команды не вычисляются в конкретное значение. Некоторые команды могут вклю- чать выражения — как, например, команда присваивания spam
    =
    2
    +
    2
    или команда if myName
    ==
    'Zophie':
    В Python 3 используется функция print()
    , а в Python 2 вместо нее существовала команда print
    . Может показаться, что различия сводятся к добавлению круглых скобок, но важно заметить, что функция print()
    в Python 3 имеет возвращаемое

    Частые ошибки при использовании терминов
    153
    значение (которое всегда равно
    None
    ), может передаваться в аргументе другим функциям и может присваиваться переменным. С командами все эти действия невозможны. Впрочем, круглые скобки допустимо использовать и в Python 2, как показывает следующий пример в интерактивной оболочке:
    >>> print 'Hello, world!' # Выполняется в Python 2
    Hello, world!
    >>> print('Hello, world!') # Выполняется в Python 2

    Hello, world!
    И хотя все выглядит как вызов функции

    , на самом деле это команда print со строковым значением, заключенным в круглые скобки, — по аналогии с тем, как присваивание spam
    =
    (2
    +
    2)
    эквивалентно spam
    =
    2
    +
    2
    . В Python 2 и 3 можно пере- дать несколько значений команде print или функции print()
    соответственно.
    В Python 3 это выглядит так:
    >>> print('Hello', 'world') # Выполняется в Python 3
    Hello world
    Но использование того же кода в Python 2 будет интерпретировано как передача кортежа с двумя строковыми значениями в команде print
    , в результате чего вы получите следующий вывод:
    >>> print('Hello', 'world') # Выполняется в Python 2
    ('Hello', 'world')
    Между командой и выражением, состоящим из вызова функции, существуют не- очевидные, но реальные различия.
    Блок, секция и тело
    Термины «блок», «секция» и «тело» часто используются как синонимы для обозна- чения группы инструкций Python. Блок (block) начинается с отступа и завершается там, где отступ возвращается к предыдущему уровню. Например, код, следующий за командой if или for
    , называется блоком команды. Новый блок должен следовать за командами, завершающимися двоеточием (такими как if
    , else
    , for
    , while
    , def
    , class и т. д.).
    Впрочем, Python допускает однострочные блоки. Это допустимый, хотя и не реко- мендуемый синтаксис Python:
    if name == 'Zophie': print('Hello, kitty!')
    В блок команды if можно включить несколько команд, разделяя их точкой с за- пятой
    ;
    :
    if name == 'Zophie': print('Hello, kitty!'); print('Do you want a treat?')

    154
    Глава 7.Жаргон программистов
    Однострочный синтаксис не может использоваться с другими командами, которым требуется новый блок. Следующий фрагмент не является допустимым в Python:
    if name == 'Zophie': if age < 2: print('Hello, kitten!')
    Он недопустим, потому что, если в следующей строке будет располагаться команда else
    , мы не сможем однозначно сказать, к какой команде if она относится.
    В официальной документации Python предпочтение отдается термину секция
    (clause) вместо «блок» (https://docs.python.org/3/reference/compound_stmts.html).
    Следующий код является секцией:
    if name == 'Zophie':
    print('Hello, kitty!')
    print('Do you want a treat?')
    Команда if является заголовком секции, а два вызова print()
    , вложенных в if
    , являются телом (body) секции. В официальной документации Python термином
    «блок» обозначается фрагмент кода Python, выполняемый как единое целое — например, модуль, функция или определение класса (https://docs.python.org/3/
    reference/executionmodel.html).
    Переменные и атрибуты
    Переменные (variables) — имена, ссылающиеся на объекты. Атрибутом (attribute), согласно официальной документации, называется «любое имя, следующее за точ- кой» (https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces).
    Атрибуты связываются с объектами (имя перед точкой). Например, введите сле- дующий фрагмент в интерактивной оболочке:
    >>> import datetime
    >>> spam = datetime.datetime.now()
    >>> spam.year
    2018
    >>> spam.month
    1
    В этом примере spam
    — переменная, содержащая объект datetime
    (возвращаемый вызовом datetime.datetime.now()
    ), а year и month
    — атрибуты этого объекта.
    Даже в случае, скажем, sys.exit()
    функция exit()
    считается атрибутом объекта модуля sys
    В других языках атрибуты называются полями (fields), свойствами (properties) или
    компонентными переменными (member variables).

    Частые ошибки при использовании терминов
    155
    Функции и методы
    Функция (function) — совокупность кода, выполняемого при вызове. Методом
    (method) называется функция (или вызываемый объект, см. следующий раздел), свя- занная с классом, — по аналогии с тем, как атрибут является переменной, связанной с объектом. К функциям относятся встроенные функции или функции, связанные с модулем. Например, введите следующий фрагмент в интерактивной оболочке:
    >>> len('Hello')
    5
    >>> 'Hello'.upper()
    'HELLO'
    >>> import math
    >>> math.sqrt(25)
    5.0
    В этом примере len()
    — функция, а upper()
    — метод строк. Методы также считаются атрибутами объектов, с которыми они связываются. Обратите внимание: точка не обязательно означает, что перед вами именно метод, а не функция. Функция sqrt()
    связывается с именем math
    , но это модуль, а не класс.
    Итерируемые объекты и итераторы
    Циклы for языка Python весьма гибки. Команда for i
    in range(3):
    выполняет блок кода трижды. Не стоит полагать, что вызов range(3)
    — это такой способ при- казать циклу for
    «выполнить код три раза», принятый в Python. Вызов range(3)
    возвращает объект диапазона, по аналогии с тем, как вызов list('cat')
    возвращает объект списка. Оба объекта являются примерами итерируемых объектов (iterables).
    Итерируемые объекты используются в циклах for
    . Введите следующий фрагмент в интерактивной оболочке, чтобы увидеть, как цикл for перебирает объект диа- пазона и объект списка:
    >>> for i in range(3):
    ... print(i) # тело цикла for
    0 1
    2
    >>> for i in ['c', 'a', 't']:
    ... print(i) # тело цикла for
    c a
    t

    156
    Глава 7.Жаргон программистов
    К категории итерируемых объектов также относятся все разновидности последо- вательностей (например, диапазоны, списки, кортежи и строки), а также ряд объ- ектов-контейнеров (словари, множества и объекты файлов).
    Тем не менее в этих примерах циклов for происходит нечто большее. Во внутрен- ней реализации Python вызывает встроенные функции iter()
    и next()
    для цикла for
    . При использовании цикла for итерируемые объекты передаются встроенной функции iter()
    , которая возвращает объекты-итераторы (iterators). И если итерируемый объект содержит элементы, итератор следит за тем, какой элемент будет использован в цикле следующим. При каждой итерации цикла объект- итератор передается встроенной функции next()
    для получения следующего элемента в итерируемом объекте. Вы можете вызвать функции iter()
    и next()
    вручную, чтобы увидеть, как работают циклы for
    . Введите следующий фрагмент в интерактивной оболочке, чтобы выполнить те же инструкции, что и в преды- дущем примере цикла:
    >>> iterableObj = range(3)
    >>> iterableObj
    range(0, 3)
    >>> iteratorObj = iter(iterableObj)
    >>> i = next(iteratorObj)
    >>> print(i) # тело цикла for
    0
    >>> i = next(iteratorObj)
    >>> print(i) # тело цикла for
    1
    >>> i = next(iteratorObj)
    >>> print(i) # тело цикла for
    2
    >>> i = next(iteratorObj)
    Traceback (most recent call last):
    File "", line 1, in
    StopIteration

    Обратите внимание: если вызвать next()
    после того, как был возвращен последний элемент в итерируемом объекте, Python выдает исключение
    StopIteration

    . Вме- сто того чтобы аварийно завершать программы с сообщением об ошибке, циклы for в Python перехватывают это исключение, чтобы знать, когда следует остановить перебор.
    Итератор способен перебрать все элементы итерируемого объекта только один раз, так же, как можно только один раз вызвать open()
    и readlines()
    для чтения со- держимого файла, после чего вам придется открывать файл заново для чтения его содержимого. Если потребуется снова перебрать итерируемый объект, необходимо снова вызвать iter()
    для создания другого итератора. Вы можете создать столько объектов-итераторов, сколько потребуется; каждый объект будет отслеживать

    Частые ошибки при использовании терминов
    157
    следующий возвращаемый элемент независимо от других. Чтобы понять, как это работает, введите следующий фрагмент в интерактивной оболочке:
    >>> iterableObj = list('cat')
    >>> iterableObj
    ['c', 'a', 't']
    >>> iteratorObj1 = iter(iterableObj)
    >>> iteratorObj2 = iter(iterableObj)
    >>> next(iteratorObj1)
    'c'
    >>> next(iteratorObj1)
    'a'
    >>> next(iteratorObj2)
    'c'
    Помните, что итерируемые объекты передаются в аргументах функции iter()
    , тогда как объект, возвращаемый вызовами iter()
    , является итератором. Объек- ты-итераторы передаются функции next()
    . Когда вы создаете собственные типы данных командами class
    , вы можете реализовать специальные методы
    __iter__()
    и
    __next__()
    , чтобы ваши объекты можно было использовать в циклах for
    Синтаксические ошибки, ошибки времени выполнения
    и семантические ошибки
    Известно много способов классификации ошибок. Но на верхнем уровне ошибки программирования можно разделить на три вида: синтаксические, ошибки времени выполнения и семантические.
    Cинтаксис (syntax) — это набор правил для создания инструкций, действительных в заданном языке программирования. Синтаксическая ошибка (например, про- пущенная круглая скобка, точка вместо запятой или другая опечатка) немедленно приводит к ошибке
    SyntaxError
    . Синтаксические ошибки также называются ошиб-
    ками разбора (parsing errors); они происходят, когда интерпретатор Python не может разобрать текст исходного кода в действительные инструкции. В естественном языке такие ошибки можно сравнить с неправильными грамматическими кон- струкциями или бессмысленными цепочками слов. Компьютерам нужны предельно точные инструкции; они не могут прочитать мысли программиста, чтобы понять, что должна делать программа. Из-за этого программа с синтаксической ошибкой даже не запустится.
    Ошибка времени выполнения (runtime error) возникает, когда работающей програм- ме не удается выполнить некоторую операцию — скажем, открыть несуществую- щий файл или разделить число на нуль. В естественном языке ошибку времени выполнения можно сравнить с невыполнимой инструкцией типа «нарисуй квадрат с тремя сторонами». Если ошибка времени выполнения не будет исправлена,

    158
    Глава 7.Жаргон программистов программа аварийно завершается с выдачей трассировки. Но ошибки времени выполнения можно перехватить командами try
    - except
    , которые выполняют код обработки ошибок. Например, введите следующий фрагмент в интерактивной оболочке:
    >>>
    1   ...   11   12   13   14   15   16   17   18   ...   40


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