Skip to content

Функции в python

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

Функция - сущность языка программирования, которая обязательно имеет имя_функции и тело_функции; также функция может принимать определенные параметры(аргументы), выполнять определенные вычисления в теле_функции и возвращать определенное значение. Функция прекращает свою работу после возврата результата, т.е. после ключевого слова return код не выполняется.

def fn
# Пример синтаксиса простой функции
def name_fn(param1, param2): # имя функции и параметры
  '''docstring Строка документации
  Должна описывать, что делает функция,
  что означают ее параметры и какое значение она возвращает
  '''
  string1 = param1 + param2 # тело функции
  return string1 # возвращаемое значение
# Если оператор return в теле функции не описан, она возвращает None
pass fn
# Пример пустой функции
def my_fn():
  pass  # ключевое слово, которое ничего не делает и возвращает none-значения. 
  # Используется если необходимо чем-то заполнить тело объекта-python: функции, цикла и пр.

Параметры (аргументы) функции

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

  • Позиционные агрументы - аргументы передаваемые при вызове функции для которых важен порядок и количество аргументов: def my_funk(arg1, arg2, arg3). Также можно определить функцию, которая будет принимать кортеж с любым количеством позиционных аргументов: def my_funk(*args)
positioned
# Определяем функцию с позиционными аргументами
def positioned(first, second):
  """Значения присваиваются по порядку"""
  print(f"first: {first}")
  print(f"second: {second}")

def my_funk(arg1, arg2=None) # данное определение делает аргумент arg2 не обязательным
  • Аргументы с ключевыми словами - аргументы передаваемые через явное указание имени соответствующего параметра, порядок не важен. Значения по умолчанию используются, если при вызове функции не было передано никаких фактических значений. Во время выполнения функции ключевые параметры можно вызывать по имени, при этом их порядок неважен. При использовании ключевых параметров все описанные после них параметры также должны быть ключевыми.
keywords
# Определяем функцию с ключевыми элементами
def keywords(first=1, second=2):
  '''Присваиваем значения по умолчанию'''
  print(f"first: {first}")
  print(f"second: {second}")

Лямбда функция

Лямбда функция - функция, которую можно уместить в одной строке кода. Лямбда функция не имеет имени.

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

lambda
# Синтаксис лямбда-выражений включает ключевое слово lambda,
# за которым следуют имя аргументов, двоеточие и вычиляемое выражение:
lambda arguments: expression
# lambda: ключевое слово, указывающее на создание lambda функции.
# arguments: аргументы функции.
# expression: выражение, которое выполняется при вызове функции.

Примеры lambda функций:

lambda
# Простая lambda функция, которая возвращает сумму двух чисел:
add = lambda x, y: x + y
result = add(3, 5)
print(result)  # Выведет 8

# lambda функция для вычисления квадрата числа:
square = lambda x: x ** 2
result = square(4)
print(result)  # Выведет 16

# Использование lambda функции внутри вызова другой функции, например, map:
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(lambda x: x ** 2, numbers))
print(squared_numbers)  # Выведет [1, 4, 9, 16, 25]

# lambda функция внутри сортировки:
people = [('Alice', 30), ('Bob', 25), ('Charlie', 35)]
sorted_people = sorted(people, key=lambda person: person[1])
print(sorted_people)  # Выведет [('Bob', 25), ('Alice', 30), ('Charlie', 35)]

Переменные внутри функции

Важно понимать как функции работают с внешними переменными! Если переданная в функцию переменная ссылается на неизменяемый объект (int, float,tuple), то что бы ни происходило внутри тела функции, внешняя переменная не изменится; если же переменная ссылается на изменяемый объект (str, list, dict), то при изменении переменной внутри функции изметится и внешняя переменная. Поэтому внутри функции не рекомендуется изменять внешние объекты.

Области видимости переменных:

  • Локальная область видимости внутри функции. Все переменные которые передаются в функцию, либо объявляются внутри нее - видны только в теле функции, после отработки функции они не выходят наружу, если не указывать это принудительно. Для этого перед объявлением переменной необходимо использовать ключевое слово global, тогда значение такой переменной можно будет видет за пределами функции.

  • Глобальная область видимости. Все переменные, объявленные в теле основного кода, видны во всей программе, в том числе: во всех функциях. Только в функциях будут действовать свои правила приоритета: если переменная с одинаковым именем объявлена и в функции и в основном коде - приоритет будет за локальной переменной функции

global vars
# По умолчанию, глобальные переменные доступны внутри функции только для чтения
# С глобальными переменными можно полноцено работать в теле функции, используя ключевое слово global
glob_var = something # объявили глобальную переменную
def my_funk():
    global glob_var # объявляем глобальную переменную в теле функции, с помощью ключевого слова global
    glob_var = new_something # изменяем значение глобальной переменной
print(glob_var) # значение было изменено внутри тела функции

Генераторы

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

Генераторы создаются с использованием ключевого слова yield вместо return. При каждом вызове генератор возвращает указанное в yield значение, после чего замораживает состояние до следующего вызова.

yield
# Простой генератор-счетчик, который возвращающает последовательные числа
def count():
  n = 0
  while True:
    n += 1
    yield n

# Генератор для чисел Фибоначчи
def fibonacci_generator(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

# Использование генератора для вывода первых 5 чисел Фибоначчи
for number in fibonacci_generator(5):
    print(number)

Глобальная переменная name

В Python переменная __name__ является специальной встроенной переменной, которая содержит имя текущего модуля. Это означает, что значение __name__ зависит от того, как используется данный модуль. Когда модуль выполняется как самостоятельная программа, значение __name__ устанавливается в строку "__main__". Это происходит, когда модуль запускается непосредственно из командной строки или при вызове функции python -m.

Каждый файл Python, исполняемый как скрипт или импортируемый как модуль, содержит специальную переменную __name__, которая указывает на его имя. Значение __name__ зависит от того, как запускается файл:

  • Если файл запускается напрямую, переменная __name__ будет равна строке "__main__".
  • Если файл импортируется как модуль в другой скрипт, __name__ будет равно имени этого модуля (например, mymodule, если файл называется mymodule.py).

Строка "__main__" используется для проверки, запущен ли файл как основной скрипт или был импортирован. Это позволяет добавить блок кода, который будет выполняться только в случае прямого запуска, а не при импорте модуля.

__name__
# Например, предположим, у вас есть следующий код в файле example.py:
def hello_print():
    print("Hello from main function!")

def example_funk():
    # do something
   something = ''
    return something

if __name__ == "__main__":
    hello_print()

Когда файл example.py запускается, интерпретатор Python устанавливает значение __name__ в "__main__", потому что он выполняется как самостоятельная программа. Это позволяет выполнить код внутри блока if __name__ == "__main__". Если бы этот модуль был импортирован в другой модуль, __name__ был бы установлен в имя этого модуля.

Таким образом, использование if __name__ == "__main__": позволяет создавать модули, которые могут быть как самостоятельно запускаемыми программами, так и импортированными в другие модули без выполнения кода в глобальной области видимости.

Использование if __name__ == "__main__" позволяет:

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