понедельник, 7 декабря 2015 г.

Основы функций; Синтаксис объявления функции.

Функции (общее)


В процессе изучения Python, мы уже неоднократно сталкивались с функциями. Мы рассматривали встроенные функции Python, функции преобразования типов данных. Давайте конкретизируем общий вид функции, такой, какой мы видим ее при использовании:

Функция имеет название и обязательные круглые () скобочки после названия.
Вызов(обращение) к функции, происходит при помощи обращения к ее названию с круглыми скобочками в конце.
В скобочки при необходимости, мы передаем необходимую информацию (аргументы).
Скобочки могут оставаться пустыми в некоторых случаях, когда нам ничего не нужно передавать в функцию.
Функция выполняет какие-то действия, чаще над теми данными, которые мы ей передали в круглых скобочках.
Функция принимает в себя вполне определенные аргументы(типы данных, значения) и выполняет вполне определенные действия.
Функция может вернуть нам результат обработки данных.
Функция может ничего не возвращать, часто такие функции называют процедурами.
Некоторые из этих утверждений, мы будем обсуждать несколько позже, но с большей частью мы познакомимся сейчас.

Зачем нужны функции? Ответ на этот вопрос, вполне очевиден. Давайте представим на секунду, что у нас нет  такой встроенной функции как len(). Каждый раз, когда нам было бы необходимо узнать размерность строки, списка, кортежа или словаря, мы были бы вынуждены писать код, который определял бы размерность необходимого объекта. Уберите функцию zip() и нам необходимо было бы каждый раз, когда появлялась бы необходимость соединить списки или кортежи по элементно, опять таки, писать код, который реализовывал бы это действие. Причем нам нужно было бы писать это не в одном месте, а в каждом месте, где необходимо было бы реализовать действие, которое мы выполняем при помощи функции.
Во-первых, нам нужно было бы четко представлять себе алгоритмы всех действий, которые предоставляют нам готовые функции.
Во-вторых - это увеличивало бы количество кода на порядки.
в третих, у нас бы небыло методов объектов, Т.К. По своей сути, они тоже являются функциями, а это значит, что и объектов у нас тоже небыло бы. Но это уже лирика.
Возможность писать и использовать функции, позволяет нам единожды описать все необходимые нам функции и использовать их в процессе написания программы. Мы можем использовать функции столько раз, сколько нам будет необходимо. Мы можем вызывать функции там, где нам это будет нужно.
Функция - это самостоятельный участок кода, который выполняет возложенную на нее задачу. Функция не должна делать все или много, каждая функция, должна решать свою индивидуальную задачу. Если у нас будет задача, которая решается в несколько шагов, каждый шаг этой задачи можно представить в виде функции. Функции позволяют нам использовать, так называемую повторяемость кода, что означает то, что мы многократно можем использовать код, который написан в функции.

Вызовы и работа с функциями


Давайте вспомним функцию len(), которая возвращает длину(количество элементов) в списке, строке, кортеже, количество пар ключ/значение у словаря. Функция имеет конкретное имя "len", за которым следуют круглые скобочки (). Что принимает функция "len"? Аргументом для этой функции служит объект списка, словаря, кортежа, строки... Это значит, что в круглых скобочках мы указываем сам объект:
>>> len([1,2,3,4,5])
5
>>>

Или переменную, которая ссылается на этот объект:
>>> lst = [1,2,3,4,5]
>>> lst
[1, 2, 3, 4, 5]
>>> len(lst)
5
>>>

Также мы можем передать туда что-то, что вернет нам подходящий для функции аргумент:
>>> words = "Hello my dear"
>>> words
'Hello my dear'
>>> words.split(' ') # разделили строку по пробелу методом split и получили список слов
['Hello', 'my', 'dear']
>>> len(words.split(' '))
3
>>>

Делая выводы, мы можем утверждать, что в круглые скобочки после имени функции, мы должны передать что-то, что будет соответствовать необходимым данным, которые принимает функция. Будет ли это сам объект, переменная ссылающаяся на него или другая функция/метод, которая вернет нам необходимое значение.
Возвращает ли нам что-то функция "len"? Естественно, она возвращает нам число, которое будет равно количеству элементов, в переданном функции объекте. Мы можем присвоить возвращаемое значение какой-то переменной или, как мы видели на примере метода split(), передать это значение в другую функцию в виде аргумента.
>>> l = [1,2,3,4,5]
>>> len(l)
5
>>> res = len(l)
>>> res
5
>>>

Каждая функция, принимает вполне конкретное количество аргументов. Кпримеру функция int(), принимает 2 аргумента, где первый - это строка с вписанным числом, а вторым может быть указание, в какую систему счисления перевести число.
>>> int('10')
10
>>> int('10',16)
16
>>> int('10',8)
8
>>> int('10',2)
2
>>>

При передаче, несколько аргументов разделяются при помощи запятой ",". По умолчанию аргументы, если их несколько, должны передаваться в строгой последовательности, которую можно узнать при помощи функции help() или же читая документацию о необходимой функции.

Синтаксис объявления функции; Создание функций.


До сих пор мы использовали базовые функции Python, а теперь, мы будем рассматривать тему создания своих функций. Для начала, рассмотрим общие правила создания функции:
def - инструкция, с которой начинается объявление функции;
Имя функции;
Круглые скобки (), где при необходимости мы указываем переменные для принятия аргументов. После скобочек знак ":";
После идет блок кода(тело) функции.
Пример:
def name(arg1, arg2, argN):
    block code
    ...

Наличие и количество аргументов при объявлении функции, зависит от необходимости их использования, Т.Е. От логики и от того, для чего предназначена функция. Давайте объявим функцию с именем "TestPrint", функция не принимает никаких аргументов, ничего не возвращает и выводит на экран слова "Тестовый текст из моей функции, который выводится на экран":
>>> def TestPrint(): #скобочки пустые, Т.К. Функция ничего не принимает
...     print u"Тестовый текст из моей функции, который выводится на экран"
...
>>> # Теперь вызовем нашу функцию
>>> TestPrint()
Тестовый текст из моей функции, который выводится на экран
>>>

Несмотря на то, что текст на экране появился, наша функция в действительности ничего не возвращает. Возвращаемое значение, мы всегда можем сохранить в какую-то переменную:
>>> a = TestPrint()
Тестовый текст из моей функции, который выводится на экран
>>> a
>>> print a
None
>>>

Как видим, в переменную сохранился тип "None". Это стандартное возвращение Python, если функция сама по себе ничего не возвращает. Текст же выводится потому, что мы внутри функции применили оператор "print", который отвечает за вывод текста на экран.
Давайте рассмотрим следующий пример:
>>> def MyFunc():
...     print "Hello"
...
>>> MyFunc()
Hello
>>>

Функция, аналогичная предыдущей. Давайте уберем оператор "print" из нашей функции:
>>> def MyFunc():
...     "Hello"
...
>>> MyFunc()
>>>

Теперь роль "print", стала более очевидна, как только мы убрали ее из тела нашей функции, текст на экран не выводится.

За возвращение значения из функции, служит инструкция "return", после которой указываются данные, которые мы хотим вернуть. Давайте перепишем нашу функцию TestPrint() так, чтобы она возвращала текст "This my function":
>>> def TestPrint():
...     return "This my function"
...
>>> # Вызовем нашу функцию
>>> TestPrint()
'This my function'
>>> # А теперь сохраним возвращаемое значение в переменную
>>> a = TestPrint()
>>> a
'This my function'
>>>

За один вызов функции, может отработать только одна инструкция "return". После того, как функция вернет свое значение, ее работа обрывается в том месте, где был встречен "return":
>>> def func():
...     return "First return"
...     return "Second return"
...
>>> func()
'First return'
>>>

Как видим, из двух "return", был возвращен только первый и функция завершила свою работу, проигнорировав код после. В рамках функции, может быть несколько инструкций "return", но отработать может только одна. к примеру, когда функция будет при помощи ветвления if else определять, какой результат необходимо вернуть, в каждом блоке кода после if, elif или else, может быть "return", который будет возвращать необходимое значение.

Теперь посмотрим на то, каким образом объявляется функция, которая может принимать какие-то аргументы. Для начала, объявим функцию, которая будет выводить на экран, переданный в нее текст. Своеобразный "print", только написанный нашими руками и в виде функции:
>>> def myprint(string):
...     print string
...
>>> myprint('Hello!')
Hello!
>>> myprint(u"Это аналог принта!")
Это аналог принта!
>>> myprint(25)
25
>>>

Что происходит в рамках объявления и вызова этой функции? При объявлении функции, в круглых скобочках мы написали слово "string". "string" - это переменная, в которую при вызове функции, попадает переданный этой функции аргумент, в нашем случае строка или число. Внутри функции, мы можем работать с переменной "string", как с обычной переменной, коей она и является. Когда мы вызываем нашу функцию myprint() и передаем в круглых скобочках строку 'Hello', она попадает во временную переменную с именем "string", с которой мы можем работать внутри нашей функции, в данном случае, просто выводим содержимое нашей переменной "string" на экран.
Давайте объявим функцию с двумя аргументами, которые будут принимать какие-то числа. Функция будет возвращать сумму этих чисел.
>>> def plus(a, b):
...     return a + b
...
>>> plus(5, 3)
8
>>> plus(10, 5)
15
>>>

Наша функция принимает 2 аргумента. При объявлении функции, мы указали, что аргументы будут попадать в переменные "a" и "b". Это значит, что при вызове функции, первое число,указанное в скобочках, попадет в переменную "a", а второе в переменную "b". Аргументы будут располагаться во временых переменных функции в том порядке, в котором объявлены переменные при создании функции, и в том порядке, в котором мы передадим аргументы при вызове функции, Т.Е. Мы объявили при создании функции, что она будет принимать аргументы в переменные (a, b), при вызове функции, если мы укажем в круглых скобочках (5, 2), переменная "a", примет в себя число 5, а переменная "b" - 2. Далее при помощи инструкции "return", нам возвращается сумма значений переменных "a" и "b". В дальнейшем, мы познакомимся с разнообразными вариантами передачи аргументов в функции.
Давайте для примера, объявим еще несколько функций. Например функцию, которая будет возвращать нам True, если мы передадим в нее парное число и False, если передадим непарное число. Это пример функции, которая содержит в себе несколько "return".
>>> def pair(num):
...     if num % 2 == 0:
...             return True
...     else:
...             return False
...
>>> pair(2)
True
>>> pair(3)
False
>>> pair(22)
True
>>> pair(33)
False
>>>

Как видим, наша функция содержит конструкцию if else, где if проверяет переданное в функцию число получением остатка от деления на 2 при помощи оператора "%" и, если выходит 0 - значит число парное, возвращает нам True, а если не ноль, отрабатывает блок кода после else и return возвращает нам False.
Давайте создадим еще чуть более сложную функцию, которая будет принимать в виде аргумента список чисел и выводить нам на экран общее количество элементов списка, количество парных и количество непарных чисел в списке.
>>> def countpair(lst):
...     pair = 0
...     unpair = 0
...     for i in lst:
...             if i % 2 == 0:
...                     pair += 1
...             else:
...                     unpair += 1
...     print u"Всего чисел - {0}, парных - {1}, непарных - {2}".format(len(lst)
,pair,unpair)
...
>>> countpair([2,1,5,3,7,4,5,2,8,6,1,8,2,2,5,2])
Всего чисел - 16, парных - 9, непарных - 7
>>> mylist = [1,1,2,2,1,5,2,7,4,4,8,6,4,2,7,4,2,1,7,6,3,7,8,5,3,2,8,5,6]
>>> countpair(mylist)
Всего чисел - 29, парных - 16, непарных - 13
>>>

Красиво, функционально и удобно, правда? В нашей функции, происходит следующее:
Функция принимает список чисел во временную переменную аргумента - "lst". Внутри функции создаются две переменные-счетчика, в которые мы будем записывать количество парных (pair) и непарных (unpair) чисел. Далее мы запускаем наш список, который находится во временной переменной "lst" в цикл for, который пробегается по элементам списка. В цикле for, написана уже знакомая нам конструкция, которая определяет парность или непарность числа. Если число парное, добавляется единичка в нашу переменную "pair", которая отвечает за количество парных чисел, а если число не парное, единичка добавляется в переменную "unpair, которая отвечает за количество непарных чисел. В конце функции, при помощи оператора print, мы выводим на экран строку, отформатированную методом format(), в который первым аргументом для разворачивания вместо {0}, мы передаем длинну списка, тутже узнавая ее при помощи функции len(), вторым аргументом для разворачивания вместо {1}, переменную pair, третим аргументом для разворачивания вместо {2}, передаем переменную unpair.

Комментариев нет:

Отправить комментарий