W3docs

Функции Python

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

Функция — это именованный, повторно используемый блок кода, выполняющий конкретную задачу. Функции позволяют написать логику один раз и вызывать её из любого места программы — делая код короче, удобнее для чтения и проще в тестировании. Эта глава охватывает всё необходимое для уверенной работы с функциями Python: определение, параметры, возвращаемые значения, аргументы по умолчанию, *args и **kwargs, область видимости, docstrings, аннотации типов, рекурсию и использование функций как объектов первого класса.

Определение функции

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

def greet(name):
    print("Hello, " + name)

Функция не выполняется до тех пор, пока вы её не вызовете. В момент определения ничего не происходит — Python лишь сохраняет объект функции под указанным именем.

Вызов функции

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

python— editable, runs on the server

Возвращаемые значения

Функция может отправить результат обратно вызывающему коду с помощью оператора return. Без return Python возвращает None.

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

result = add(3, 5)
print(result)  # 8

После выполнения return функция немедленно останавливается — любой код после него в теле той же функции недостижим.

Возврат нескольких значений

Python позволяет возвращать несколько значений в виде кортежа, который можно распаковать на стороне вызова.

import math

def circle_stats(radius):
    area = math.pi * radius ** 2
    circumference = 2 * math.pi * radius
    return area, circumference

area, circ = circle_stats(5)
print(round(area, 2))   # 78.54
print(round(circ, 2))   # 31.42

Параметры и аргументы

ТерминЗначение
ПараметрИмя переменной в определении функции
АргументФактическое значение, передаваемое при вызове функции

Python поддерживает несколько способов передачи аргументов.

Позиционные аргументы

Аргументы сопоставляются с параметрами по порядку.

def describe(name, age):
    print(name, "is", age, "years old")

describe("Bob", 25)   # Bob is 25 years old

Именованные аргументы

Аргументы можно передавать по имени, в любом порядке.

describe(age=25, name="Bob")   # Bob is 25 years old

Значения параметров по умолчанию

Укажите запасное значение, которое используется, когда вызывающий код не передаёт данный аргумент.

def greet(name="World"):
    print("Hello, " + name)

greet()         # Hello, World
greet("Alice")  # Hello, Alice

Важно: никогда не используйте изменяемый объект (список, словарь) в качестве значения по умолчанию — он создаётся один раз при определении функции и разделяется между всеми вызовами. Вместо этого используйте None в качестве значения по умолчанию и создавайте объект внутри тела функции.

# Correct pattern for a mutable default
def append_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

Произвольное число позиционных аргументов (*args)

Добавьте префикс * к имени параметра, чтобы собрать любое количество позиционных аргументов в кортеж.

def total(*numbers):
    return sum(numbers)

print(total(1, 2, 3))    # 6
print(total(10, 20))     # 30

Произвольное число именованных аргументов (**kwargs)

Добавьте префикс **, чтобы собрать любое количество именованных аргументов в словарь.

def describe_person(**info):
    for key, value in info.items():
        print(key + ": " + str(value))

describe_person(name="Alice", age=30, city="Paris")
# name: Alice
# age: 30
# city: Paris

Комбинирование типов параметров

При смешивании типов параметров порядок должен быть следующим: позиционные, *args, только именованные, **kwargs.

def log(level, *messages, separator=" | ", **meta):
    print(level.upper(), separator.join(messages), meta)

log("info", "started", "ready", separator=" — ", version="1.0")
# INFO started — ready {'version': '1.0'}

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

Правила области видимости Python следуют правилу LEGB: Local → Enclosing → Global → Built-in.

Переменная, определённая внутри функции, является локальной — к ней нельзя обратиться снаружи.

def my_func():
    x = 10          # local to my_func
    print(x)

my_func()
# print(x)  # NameError: name 'x' is not defined

Чтобы прочитать или изменить глобальную переменную внутри функции, объявите её с помощью global.

x = 10

def change_x():
    global x
    x = 20

change_x()
print(x)   # 20

Используйте global осторожно — функции, зависящие от глобального состояния, сложнее тестировать и переиспользовать. Подробнее об области видимости читайте в разделах Переменные Python и Глобальные переменные.

Docstrings

Docstring — это строковый литерал, размещённый сразу после строки def. Он документирует, что делает функция, что принимает и что возвращает. Python хранит его в атрибуте __doc__ функции, а такие инструменты, как help(), отображают его.

def add(a, b):
    """Return the sum of a and b.

    Args:
        a: First number.
        b: Second number.

    Returns:
        The sum as a number.
    """
    return a + b

print(add.__doc__)
# Return the sum of a and b.
# ...

Аннотации типов

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

def multiply(a: float, b: float) -> float:
    return a * b

print(multiply(3, 4))      # 12
print(multiply(2.5, 2.0))  # 5.0

Рекурсия

Функция может вызывать саму себя. Это называется рекурсией и полезно для задач с естественно рекурсивной структурой (деревья, факториалы и т. д.). Каждая рекурсивная функция должна иметь базовый случай, останавливающий рекурсию.

def factorial(n):
    if n == 0 or n == 1:   # base case
        return 1
    return n * factorial(n - 1)

print(factorial(5))   # 120
print(factorial(0))   # 1

Python ограничивает глубину рекурсии (по умолчанию 1000), чтобы предотвратить переполнение стека. При глубокой рекурсии предпочтительнее использовать итеративный подход или sys.setrecursionlimit.

Функции как объекты первого класса

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

def apply(func, value):
    return func(value)

def double(n):
    return n * 2

print(apply(double, 7))   # 14

Это основа для лямбда-функций, функций высшего порядка и декораторов.

Встроенные функции и пользовательские функции

Python поставляется со множеством встроенных функцийprint(), len(), range(), sum(), sorted() — которые всегда доступны без импорта. Пользовательские функции — это те, которые вы пишете с помощью def. Синтаксис вызова у них одинаковый.

Рекомендации

  • Называйте функции глаголами: calculate_tax() яснее, чем tax().
  • Делайте одно дело: функция, которая проверяет, сохраняет и отправляет письмо — это три функции, ожидающие своего часа.
  • Пишите docstring: даже одно предложение с описанием назначения имеет ценность.
  • Избегайте побочных эффектов там, где это возможно: функции, которые возвращают значения и не изменяют глобальное состояние, легче тестировать.
  • Держите сигнатуры короткими: более трёх-четырёх параметров — это сигнал сгруппировать связанные данные в класс или словарь.
  • Используйте аннотации типов: они служат лёгкой документацией и позволяют выполнять статический анализ.

Практика

Практика
Which keyword is used to define a function in Python?
Which keyword is used to define a function in Python?
Was this page helpful?