image
Главная // Блог // Основы программирования // Функции в языке программирования Python. Часть 1.

Функции в языке программирования Python. Часть 1.

Функции Python. Часть 1 

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

Синтаксис функций

Функции в Python - это именованные блоки кода, которые начинаются с ключевого слова def, названия функции, аргументов которые она принимает и двоеточия. По правилам хорошего тона, имя функции не должно содержать заглавных символов, а слова в названии отделяются нижними подчеркиваниями. В качестве примера рассмотрим функцию hello_world, которая печатает в консоль эту фразу:

def hello_world():
   print('Hello World!')

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

hello_world() #Hello World!

Писать функции, которые не принимают на вход аргументов и ничего не возвращают - скучно, не так ли? Давайте посмотрим, как будет выглядеть функция сложения двух элементов:

def add(a, b):
   return a + b

Функция add принимает в себя 2 числа и возвращает их сумму. На самом деле, совсем необязательно подавать числа, функция отработает верно, если внутрь подать 2 строки или 2 списка. Python является очень гибким языком программирования и имеет нестрогую типизацию, поэтому одну и ту же функцию можно применять для разных задач.

print(add(5, 5)) #10
print(add('Hello ', 'World!')) #Hello World!

С помощью ключевого слова return функция понимает, какой результат необходимо выдать пользователю, если же return не прописан, то функция выдаст None.

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

def add_and_mult(a, b):
   return a + b, a*b

print(add_and_mult(5, 5)) #(10, 25)

Как можно увидеть из примера, функция add_and_mult возвращает кортеж

результатов сложения и умножения двух чисел. Из этого можно сделать вывод, что помимо простых типов данных, таких как int, float, string и т.д., с помощью return можно получить объекты любой сложности: списки, кортежи, словари и т.д.

Аргументы, которые подаются на вход нашей функции могут как обязательными, так и необязательными. Это удобно, если наша функция должна выполнять разные задачи, например, напишем функцию, которая в зависимости от необязательной переменной будет либо складывать, либо умножать 2 числа. Для того чтобы необязательность аргумента проявилась, необходимо присвоить ему какое-то значение по умолчанию, в нашем случае мы будем подавать строку, на основе которой функция решит что ей делать - складывать или умножать:

def add_or_mult(a, b, operation='add'):
    if operation == 'add':
        return a + b
    elif operation == 'mul':
        return a*b
    else:
        pass

print(add_or_mult(5, 5)) #10
print(add_or_mult(5, 5, operation='mul)) #25
print(add_or_mult(5, 5, operation='')) #None

В первом случае используется аргумент по умолчанию, поэтому функция складывает аргументы, которые в нее передаются, и получается ответ 10. Во втором случае, мы явно указываем функции о том, что мы хотим эти числа перемножить и получаем абсолютно закономерный результат 25. В третьем же случае, мы явно определили аргумент operation, но ну уточнили, что именно мы хотим сделать, поэтому получили результат None. Оператор pass означает пустую операцию, по сути, программа не поняла, что же мы от нее хотим и ничего нам не вернула. Более правильно конечно было сделать обработчик ошибок, который будет обрабатывать такие ситуации, но для понимания операция if - else проще.

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

def specification(a: int, b: int) -> (list, int):
    return [a, b], a + b

print(specification(5, 10))

Область видимости

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

. С помощью ключевого слова global - мы можем объявлять переменную, которая будет видна извне, однако такой подход не является хорошим тоном, у программистов принято все так обходиться исключительно локальными переменными, поскольку при написании большой программы переменную, объявленную глобально можно случайно переопределить, что может вызвать ошибку.

def add_glob(a):
    global g
    g = 10
    return a + g


def add_local():
    a, b = 5, 5
    return a + b


def add_combine(a):
    return a + g

print(add_glob(5)) #15
print(add_local()) #10
print(add_combine(10)) #20

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

Неопределенное число аргументов в функции

Не всегда пользователь может четко задать количество аргументов, которое будет использоваться в функции, для этого придумана система, которая может позволять передавать различное число параметров, это достигается с помощью директив *args и **kwargs, сами ключевые слова в данном примере номинальные, можно использовать любые названия, важно добавить * или **.

Различия между *args и **kwargs в типе данных, которые мы передаем в функцию, если мы используем *args, то на вход следует подавать кортеж, а если же **kwargs, то словарь. Это очень удобные директивы, позволяющие писать сложные методы с широким функционалом. Взглянем на примеры:

def func_tuple(*args):
    s = 0
    for i in args:
        s += i
    return s


def func_dict(**kwargs):
    s = ''
    for key in kwargs:
        s += kwargs[key]
    print(s)


print(func_tuple(5)) #5
print(func_tuple(5, 10)) #15
print(func_tuple(5, 10, 15, 78, 24)) #132


func_dict(hello='Hello ', world='World!') #Hello World!
func_dict(russia='Moscow ', usa='Washington ', england='London') #Moscow Washington London

В наших примерах мы передаем различное число аргументов в одну и ту же функцию, а на результате получаем абсолютно одинаковую работу нашей программы. С учетом того, что программистам часто приходится работать с внешними данными, размер которых неизвестен, а обрабатывать надо все одинаково, *args и **kwargs являются настоящим подарком от разработчиков Python. 

Рекурсия

Иногда при написании программы требуется, чтобы функция вызывалась внутри себя, наиболее простым примером является поиск факториала:

def factorial(x):
    if x <= 1:
        return 1
    else:
        return x*factorial(x - 1)

print(factorial(6)) #720


В данном примере, мы вызывали функцию factorial внутри себя, что позволило нам рассчитать значение факториала от 6.

Заключение

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


Теги: python


Оставить комментарий
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.

Похожие новости

Искусственный интеллект — это просто!