1.74M
Категория: ПрограммированиеПрограммирование

Алгоритмизация и программирование/ лекция 2

1.

АЛГОРИТМИЗАЦИЯ
И ПРОГРАММИРОВАНИЕ
Лекция 2

2.

План
• Область видимости переменных
• Модули
• Обработка исключений
• Списки
• Кортежи

3.

Область видимости переменных
Область видимости или scope определяет контекст переменной, в
рамках которого ее можно использовать. В Python есть два типа
контекста: глобальный и локальный.

4.

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

5.

Область видимости переменных
Здесь переменная name является глобальной и имеет глобальную
область видимости. И обе определенные здесь функции могут
свободно ее использовать.

6.

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

7.

Область видимости переменных
В данном случае в каждой из двух функций определяется
локальная переменная name. И хотя эти переменные называются
одинаково, но тем не менее это дву разных переменных, каждая из
которых доступна только в рамках своей функции. Также в функции
say_hi определена переменная surname, которая также является
локальной, поэтому в функции say_bye мы ее использовать не
сможем.

8.

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

9.

Область видимости переменных
Здесь определена глобальная переменная name. Однако в
функции say_bye определена локальная переменная с тем же
именем name. И если функция say_hi использует глобальную
переменную, то функция say_bye использует локальную
переменную, которая скрывает глобальную.

10.

Область видимости переменных
Если же мы хотим изменить в локальной функции глобальную
переменную, а не определить локальную, то необходимо
использовать ключевое слово global:

11.

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

12.

Область видимости переменных
В данном случае число 3.14 представлено константой PI. Понятно,
что это значение в принципе не изменится, поэтому его можно
вынести из функций и определить в виде константы. Как правило,
имя константы определяется заглавными буквами.

13.

Модули
Модуль в языке Python представляет отдельный файл с кодом,
который можно повторно использовать в других программах.
Для создания модуля необходимо создать собственно файл с
расширением *.py, который будет представлять модуль. Название
файла будет представлять название модуля. Затем в этом файле
надо определить одну или несколько функций.

14.

Модули
Для этого сначала определим новый модуль: создадим новый
файл, который назовем service.py, в той же папке, где находится
hello.py.

15.

Модули
Соответственно модуль будет называться service. И определим в нем
следующий код:
Здесь определена функция calculate_income, которая в качестве
параметров получает процентную ставку вклада, сумму вклада и
период, на который делается вклад, и высчитывает сумму, которая
получится в конце данного периода.

16.

Модули
В файле hello.py используем данный модуль:
Для использования модуля его надо импортировать с помощью
оператора import, после которого указывается имя модуля: import
service.

17.

Модули
Чтобы обращаться к функциональности модуля, нам нужно
получить его пространство имен. По умолчанию оно будет
совпадать с именем модуля, то есть в нашем случае также будет
называться service.
Получив пространство имен модуля, мы сможем обратиться к его
функциям по схеме пространство_имен.функция:
service.calculate_income(rate, money, period)

18.

Модули
И после этого мы можем запустить главный скрипт hello.py, и он
задействует модуль service.py. В частности, консольный вывод мог
бы быть следующим:

19.

Модули
Настройка пространства имен
По умолчанию при импорте модуля он доступен через одноименное
пространство имен. Однако мы можем переопределить это поведение. Так,
ключевое слово as позволяет сопоставить модуль с другим пространством
имен. Например:
В данном случае пространство имен будет называться srv.

20.

Модули
Другой вариант настройки предполагает импорт функциональности
модуля в глобальное пространство имен текущего модуля с помощью
ключевого слова from:
В данном случае мы импортируем из модуля service в глобальное
пространство имен функцию calculate_income. Поэтому мы сможем ее
использовать без указания пространства имен модуля как если бы она
была определена в этом же файле.

21.

Модули
Если бы в модуле service было бы несколько функций, то могли бы их
импортировать в глобальное пространство имен одним выражением:
Но стоит отметить, что импорт в глобальное пространство имен чреват
коллизиями имен функций. Например, если у нас том же файле определена
функция с тем же именем, то при вызове функции мы можем получить
ошибку. Поэтому лучше избегать использования импорта в глобальное
пространство имен.

22.

Модули
Имя модуля
В примере выше модуль hello.py, который является главным, использует
модуль service.py. При запуске модуля hello.py программа выполнит всю
необходимую работу. Однако, если мы запустим отдельно модуль service.py
сам по себе, то ничего на консоли не увидим. Ведь модуль просто определяет
функцию и не выполняет никаких других действий. Но мы можем сделать так,
чтобы модуль service.py мог использоваться как сам по себе, так и
подключаться в другие модули.
При выполнении модуля среда определяет его имя и присваивает его
глобальной переменной __name__ (с обеих сторон два подчеркивания). Если
модуль является запускаемым, то его имя равно __main__ (также по два
подчеркивания с каждой стороны). Если модуль используется в другом
модуле, то в момент выполнения его имя аналогично названию файла без
расширения py. И мы можем это использовать.

23.

Модули
Так, изменим содержимое файла service.py:
Кроме того, для тестирования функции определена главная функция main. И мы
можем сразу запустить файл service.py отдельно от всех и протестировать код.

24.

Модули
Следует обратить внимание на вызов функции main:
if __name__=="__main__":
main()
Переменная __name__ указывает на имя модуля. Для главного модуля, который
непосредственно запускается, эта переменная всегда будет иметь значение __main__
вне зависимости от имени файла.
Поэтому, если мы будем запускать скрипт service.py отдельно, сам по себе, то Python
присвоит переменной __name__ значение __main__, далее в выражении if вызовет
функцию main из этого же файла.
Однако если мы будем запускать другой скрипт, а этот - service.py - будем подключать
в качестве вспомогательного, для service.py переменная __name__ будет иметь
значение service. И соответственно метод main в файле service.py не будет работать.
Данный подход с проверкой имени модуля является более рекомендуемым
подходом, чем просто вызов метода main.

25.

Модули
В файле hello.py также можно сделать проверку на то, является ли
модуль главным (хотя в принципе это необязательно):

26.

Обработка исключений
При программировании на Python мы можем столкнуться с двумя
типами ошибок. Первый тип представляют синтаксические ошибки
(syntax error). Они появляются в результате нарушения синтаксиса
языка программирования при написании исходного кода. При
наличии таких ошибок программа не может быть скомпилирована.
При работе в какой-либо среде разработки, например, в PyCharm,
IDE сама может отслеживать синтаксические ошибки и каким-либо
образом их выделять.

27.

Обработка исключений
Второй тип ошибок представляют ошибки выполнения (runtime error).
Они появляются в уже скомпилированной программе в процессе ее
выполнения. Подобные ошибки еще называются исключениями.
Например, в прошлых темах мы рассматривали преобразование числа в
строку:
Данный скрипт успешно скомпилируется и выполнится, так как строка
"5" вполне может быть конвертирована в число.

28.

Обработка исключений
Однако возьмем другой пример:
При выполнении этого скрипта будет выброшено исключение
ValueError, так как строку "hello" нельзя преобразовать в число.

29.

Обработка исключений
С одной стороны, здесь очевидно, сто строка не представляет
число, но мы можем иметь дело с вводом пользователя, который
также может ввести не совсем то, что мы ожидаем:

30.

Обработка исключений
При возникновении исключения работа программы прерывается, и чтобы избежать
подобного поведения и обрабатывать исключения в Python есть
конструкция try..except, которая имеет следующее формальное определение:
try:
инструкции
except [Тип_исключения]:
инструкции
Весь основной код, в котором потенциально может возникнуть исключение,
помещается после ключевого слова try. Если в этом коде генерируется исключение,
то работа кода в блоке try прерывается, и выполнение переходит в блок except.
После ключевого слова except опционально можно указать, какое исключение будет
обрабатываться (например, ValueError или KeyError). После слова except на
следующей стоке идут инструкции блока except, выполняемые при возникновении
исключения.

31.

Обработка исключений
Рассмотрим обработку исключения на примере преобразовании
строки в число:

32.

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

33.

Обработка исключений
Если ситуация такова, что в программе могут быть сгенерированы
различные типы исключений, то мы можем их обработать по
отдельности, используя дополнительные выражения except:

34.

Обработка исключений
Если возникнет исключение в результате преобразования строки в
число, то оно будет обработано блоком except ValueError. Если же
второе число будет равно нулю, то есть будет деление на ноль,
тогда возникнет исключение ZeroDivisionError, и оно будет
обработано блоком except ZeroDivisionError.
Тип Exception представляет общее исключение, под которое
попадают все исключительные ситуации. Поэтому в данном случае
любое исключение, которое не представляет тип ValueError или
ZeroDivisionError, будет обработано в блоке except Exception:.

35.

Обработка исключений
Если возникнет исключение в результате преобразования строки в
число, то оно будет обработано блоком except ValueError. Если же
второе число будет равно нулю, то есть будет деление на ноль,
тогда возникнет исключение ZeroDivisionError, и оно будет
обработано блоком except ZeroDivisionError.
Тип Exception представляет общее исключение, под которое
попадают все исключительные ситуации. Поэтому в данном случае
любое исключение, которое не представляет тип ValueError или
ZeroDivisionError, будет обработано в блоке except Exception:.

36.

Обработка исключений
Блок finally
При обработке исключений также можно использовать необязательный
блок finally. Отличительной особенностью этого блока является то, что
он выполняется вне зависимости, было ли сгенерировано исключение:
Как правило, блок finally применяется для освобождения используемых
ресурсов, например, для закрытия файлов.

37.

Обработка исключений
Получение информации об исключении
С помощью оператора as мы можем передать всю информацию об
исключении в переменную, которую затем можно использовать в
блоке except:

38.

Обработка исключений
Генерация исключений
Иногда возникает необходимость вручную сгенерировать то или иное исключение. Для этого
применяется оператор raise. При вызове исключения мы можем ему передать сообщение, которое
затем можно вывести пользователю.

39.

Списки
Для работы с наборами данных Python предоставляет такие
встроенные типы как списки, кортежи и словари.
Список (list) представляет тип данных, который хранит набор или
последовательность элементов. Для создания списка в квадратных
скобках ([]) через запятую перечисляются все его элементы. Во
многих языках программирования есть аналогичная структура
данных, которая называется массив. Например, определим список
чисел:

40.

Списки
Также для создания списка можно использовать конструктор list():
Оба этих определения списка аналогичны - они создают пустой
список.
Конструктор list для создания списока может принимать другой
список:

41.

Списки
Для обращения к элементам списка надо использовать индексы, которые
представляют номер элемента в списка. Индексы начинаются с нуля. То есть
второй элемент будет иметь индекс 1. Для обращения к элементам с конца
можно использовать отрицательные индексы, начиная с -1. То есть у
последнего элемента будет индекс -1, у предпоследнего - -2 и так далее.

42.

Списки
Если необходимо создать список, в котором повторяется одно и то
же значение несколько раз, то можно использовать символ
звездочки *. Например, определим список из шести пятерок:

43.

Списки
Кроме того, если нам необходим последовательный список чисел,
то для его создания удобно использовать функцию range, которая
имеет три формы:
range(end): создается набор чисел от 0 до числа end
range(start, end): создается набор чисел от числа start до числа end
range(start, end, step): создается набор чисел от числа start до числа
end с шагом step

44.

Списки
Список необязательно должен содержать только однотипные
объекты. Мы можем поместить в один и тот же список
одновременно строки, числа, объекты других типов данных:

45.

Списки
Перебор элементов
Для перебора элементов можно использовать как цикл for, так и цикл while.
Перебор с помощью цикла for:
Здесь вместо функции range мы сразу можем подставить имеющийся список companies.

46.

Списки
Перебор с помощью цикла while:
Для перебора с помощью функции len() получаем длину списка. С
помощью счетчика i выводит по элементу, пока значение счетчика не
станет равно длине списка.

47.

Списки
Сравнение списков
Два списка считаются равными, если они содержат один и тот же набор
элементов:
В данном случае оба списка будут равны.

48.

Списки
Методы и функции по работе со списками
Для управления элементами списки имеют целый ряд методов. Некоторые из них:
• append(item): добавляет элемент item в конец списка
• insert(index, item): добавляет элемент item в список по индексу index
• remove(item): удаляет элемент item. Удаляется только первое вхождение элемента. Если элемент не
найден, генерирует исключение ValueError
• clear(): удаление всех элементов из списка
• index(item): возвращает индекс элемента item. Если элемент не найден, генерирует исключение
ValueError
• pop([index]): удаляет и возвращает элемент по индексу index. Если индекс не передан, то просто
удаляет последний элемент.
• count(item): возвращает количество вхождений элемента item в список
• sort([key]): сортирует элементы. По умолчанию сортирует по возрастанию. Но с помощью параметра
key мы можем передать функцию сортировки.
• reverse(): расставляет все элементы в списке в обратном порядке

49.

Списки
Кроме того, Python предоставляет ряд встроенных функций для
работы со списками:
• len(list): возвращает длину списка
• sorted(list, [key]): возвращает отсортированный список
• min(list): возвращает наименьший элемент списка
• max(list): возвращает наибольший элемент списка

50.

Списки
Добавление и удаление
элементов
Для добавления элемента
применяются
методы append() и insert, а для
удаления методы remove(), pop() и clear().
Использование методов:

51.

Списки
Проверка наличия элемента
Если определенный элемент не найден, то методы remove и index генерируют исключение. Чтобы
избежать подобной ситуации, перед операцией с элементом можно проверять его наличие с помощью
ключевого слова in:
Выражение item in companies возвращает True, если элемент item имеется в списке companies. Поэтому
конструкция if item in companies может выполнить последующий блок инструкций в зависимости от
наличия элемента в списке.

52.

Списки
Подсчет вхождений
Если необходимо узнать, сколько раз в списке присутствует тот или
иной элемент, то можно применить метод count():

53.

Списки
Сортировка
Для сортировки по возрастанию применяется метод sort():
Если необходимо отсортировать данные в обратном порядке, то
мы можем после сортировки применить метод reverse():

54.

Списки
При сортировке фактически сравниваются два объекта, и который
из них "меньше", ставится перед тем, который "больше". Понятия
"больше" и "меньше" довольно условны. И если для чисел все
просто - числа расставляются в порядке возрастания, то для строк
и других объектов ситуация сложнее. В частности, строки
оцениваются по первым символам. Если первые символы равны,
оцениваются вторые символы и так далее. При чем цифровой
символ считается "меньше", чем алфавитный заглавный символ, а
заглавный символ считается меньше, чем строчный.

55.

Списки
Таким образом, если в списке сочетаются строки с верхним и
нижним регистром, то мы можем получить не совсем корректные
результаты, так как для нас строка "bob" должна стоять до строки
"Tom". И чтобы изменить стандартное поведение сортировки, мы
можем передать в метод sort() в качестве параметра функцию:

56.

Списки
Кроме метода sort мы можем использовать встроенную
функцию sorted, которая имеет две формы:
• sorted(list): сортирует список list
• sorted(list, key): сортирует список list, применяя к элементам функцию
key
При использовании этой функции следует учитывать, что эта функция не
изменяет сортируемый список, а все отсортированные элементы она
помещает в новый список, который возвращается в качестве результата.

57.

Списки
Минимальное и максимальное значения
Встроенный функции Python min() и max() позволяют найти
минимальное и максимальное значения соответственно:

58.

Списки
Копирование списков
При копировании списков следует учитывать, что списки
представляют изменяемый (mutable) тип, поэтому если обе
переменных будут указывать на один и тот же список, то
изменение одной переменной, затронет и другую переменную:

59.

Списки
Это так называемое "поверхностное копирование" (shallow copy).
И, как правило, такое поведение нежелательное. И чтобы
происходило копирование элементов, но при этом переменные
указывали на разные списки, необходимо выполнить глубокое
копирование (deep copy). Для этого можно использовать
метод deepcopy(), который определен во встроенном
модуле copy:

60.

Списки
Копирование части списка
Если необходимо скопировать не весь список, а только его какую-то
определенную часть, то мы можем применять специальный синтаксис.
который может принимать следующие формы:
• list[:end]: через параметр end передается индекс элемента, до
которого нужно копировать список
• list[start:end]: параметр start указывает на индекс элемента, начиная с
которого надо скопировать элементы
• list[start:end:step]: параметр step указывает на шаг, через который
будут копироваться элементы из списка. По умолчанию этот параметр
равен 1.

61.

Списки
Копирование части списка

62.

Списки
Соединение списков
Для объединения списков применяется операция сложения (+):

63.

Списки
Списки списков
Списки кроме стандартных данных типа строк, чисел, также могут
содержать другие списки. Подобные списки можно ассоциировать с
таблицами, где вложенные списки выполняют роль строк. Например:

64.

Списки
Чтобы обратиться к элементу
вложенного списка, необходимо
использовать пару
индексов: users[0][1] обращение ко второму элементу
первого вложенного списка.
Добавление, удаление и
исменение общего списка, а
также вложенных списков
аналогично тому, как это
делается с обычными
(одномерными) списками:

65.

Списки
Перебор вложенных списков:

66.

Кортежи
Кортеж (tuple) представляет последовательность элементов,
которая во многом похожа на список за тем исключением, что
кортеж является неизменяемым (immutable) типом. Поэтому мы
не можем добавлять или удалять элементы в кортеже, изменять
его.
Для создания кортежа используются круглые скобки, в которые
помещаются его значения, разделенные запятыми:

67.

Кортежи
Также для определения кортежа мы можем просто перечислить
значения через запятую без применения скобок:
Если вдруг кортеж состоит из одного элемента, то после
единственного элемента кортежа необходимо поставить запятую:

68.

Кортежи
Для создания кортежа из списка можно передать список в
функцию tuple(), которая возвратит кортеж:

69.

Кортежи
Обращение к элементам в кортеже происходит также, как и в
списке по индексу. Индексация начинается также с нуля при
получении элементов с начала списка и с -1 при получении
элементов с конца списка:

70.

Кортежи
Но так как кортеж - неизменяемый тип (immutable), то мы не сможем
изменить его элементы. То есть следующая запись работать не будет:

71.

Кортежи
При необходимости мы можем разложить кортеж на отдельные
переменные:

72.

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

73.

Кортежи
С помощью встроенной функции len() можно получить длину
кортежа:

74.

Кортежи
Перебор кортежей
Для перебора кортежа можно использовать стандартные
циклы for и while. С помощью цикла for:
С помощью цикла while:

75.

Кортежи
Как для списка с помощью выражения элемент in кортеж можно
проверить наличие элемента в кортеже:

76.

Кортежи
Сложные кортежи
Один кортеж может содержать другие кортежи в виде элементов. Например:

77.

Кортежи
Здесь кортеж countries, который представляет страны, состоит из
кортежей, каждый из которых - отдельная страна.
Вложенные кортежи имеют три элемента: название страны,
численность ее населения и города. Города представляют
отдельный кортеж, где каждый отдельный город - это вложенный
кортеж, содержащий название города и численность его
населения.
English     Русский Правила