Функции и генераторы

Повторение

Вспомним о последовательностях.

1.png

Функция range возвращает неизменяемую последовательность чисел в виде объекта range.

2.png

Из любой последовательности можно изготовит итерируемый объект.

3.png

Любой объект можно пройти поэлементно с помощью for

4.png

Из c можно изготовить итератор. Имя a связать с каждым из этих элементов. В случае возникновения исключения, просто заканчиваем цикл.

Вычислим последовательность enumerate.

5.png

Возвращаются пары: номер элемента, элемент. Рассмотрим итерируемую последовательность.

6.png

Она не индексируемая, так как последовательность, из которой мы делаем reversed может быть не индексируемой.

7.png

globals() и locals() совпадают, если мы работаем в командной строке.

8.png

Поговорим про функции

Зададим функцию. Очевидно, что функция возвратит 8. Если не писать return, то функция возвращает None.

9.png

Напишем так:

10.png

Ошибки нет! Пока мы не вызовем функцию и не начнем вычисления, нам все равно где c.

11.png

Замечание: целое к строке прибавить не можем.

Упростим функцию.

12.png

Объекты не проверяются. Это означает, что вместо чисел можно использовать любые объекты. Например, строки. Посмотрим на содержимое пространства имен. a,b,c находятся во временно созданном пространстве имен.

13.png

То пространство имен, которое достается по умолчанию, в случае вычисления функции fun оказывается другим.

А если так…

14.png

30.png

И еще так…

16.png 17.png

Если перед строкой fun(1,2) сделать print(dir(fun)), то увидим пространство имен самого объекта fun. Оно соответствует тому пространству имен, что вызывает dir(). Разберемся с тем, что происходит когда имена в глобальном и локальном пространстве имен совпадают.

18.png 19.png

В первой и второй строке глобальное пространство имен, третья строка – локальное. Если c объявить global, то она не заведется в локальном. Если имя в операторе связывания слева, то оно локальное, так как мы его создаем. Но бывают случаи, когда непонятно, какое имя локальное, а какое глобальное.

20.png 21.png

Синтаксическое сканирование производится и Python знает, что имя локальное, так как от него происходит связывание. Значит, функция просто не работающая. Это ограничивает нас от ситуации, если мы что-то перебиваем, т.е. нам не встретится ситуация стороннего эффекта.

Рассмотрим еще один пример, на котором убедимся, что функция – это полноценный объект. Мы можем передавать её другой функции, что бы она её вывела.

22.png

Еще один пример

23.png 24.png

Рассмотрим пример, в котором возникает неприятная история: "a" для fun локальная, а для fuun нет. Она лежит в промежутке. Мы не можем перебить a.

25.png

Конструкции функций, которые являются выражениями.

26.png

У lambda функции ограничена правая часть. Здесь можно написать только выражения. Но они полезны, когда не нужно значение.

Поговорим о запаковке и распаковке последовательности

Существует понятие множественное связывание. Рассмотрим пример: есть переменные, которые нужно поменять местами. Слева пишем нужное количество имен.

27.png

Так можно делать, если мы знаем количество имен при распаковке. Если мы напишем функцию

>>>def fun(a,b,c):
        return a+b+c
print(fun(1,2+2,3+..))

Что происходит с объектами 1,2,3? Формируется кортеж, он передается в контейнер функций, там распаковывается, раскладывается по a,b,c и выполняется.

Вспомним о повторно входимых функциях

28.png

Повторно вводимая функция заводит пространство имен. Вместо return используется yield.

29.png

Функция возвращает генератор. Generator object это и есть итератор.

LecturesCMC/PythonIntro2017/04_Functions/Conspect (последним исправлял пользователь AslanAshabokov 2017-12-29 15:03:37)