Python & AI Tutorials Logo
Программирование Python

19. Определение и вызов функций

19.1) Что такое функции и почему они важны

Функция(function) — это именованный блок кода, который выполняет конкретную задачу. Вы уже использовали функции на протяжении всей этой книги — print(), input(), len(), type() и многие другие. Это встроенные функции(built-in functions), которые предоставляет Python. Теперь вы научитесь создавать собственные пользовательские функции(custom functions), чтобы организовывать код и делать его переиспользуемым.

Почему функции важны

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

1. Переиспользование кода

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

python
# Без функций — повторяющийся код
length1 = 5
width1 = 3
area1 = length1 * width1
print(f"Area 1: {area1}")
 
length2 = 8
width2 = 4
area2 = length2 * width2
print(f"Area 2: {area2}")
 
length3 = 10
width3 = 6
area3 = length3 * width3
print(f"Area 3: {area3}")

Output:

Area 1: 15
Area 2: 32
Area 3: 60

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

2. Организация кода

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

3. Абстракция(abstraction)

Функции скрывают детали реализации за простым интерфейсом. Когда вы вызываете len(my_list), вам не нужно знать, как Python считает элементы — вы просто получаете результат. Аналогично, ваши функции могут предоставлять простые интерфейсы к сложным операциям, делая код проще в использовании и понимании.

4. Тестирование и отладка(debugging)

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

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

19.2) Определение функций с помощью def

Чтобы создать функцию в Python, используется ключевое слово def (сокращение от "define"). Базовая структура определения функции выглядит так:

python
def function_name():
    # Блок кода, который выполняется при вызове функции
    statement1
    statement2
    # ... больше операторов

Разберём каждую часть:

  • def: ключевое слово, которое говорит Python, что вы определяете функцию
  • function_name: имя, которое вы выбираете для своей функции (подчиняется тем же правилам, что и имена переменных)
  • (): круглые скобки, которые со временем будут содержать параметры (мы рассмотрим их в следующем разделе)
  • :: двоеточие, которое отмечает конец заголовка функции
  • Блок кода с отступом: операторы, составляющие тело функции (должны быть с отступом)

Ваша первая функция

Вот простая функция, которая печатает приветствие:

python
def greet():
    print("Hello!")
    print("Welcome to Python functions.")
 
# Вызов функции
greet()

Output:

Hello!
Welcome to Python functions.

Когда вы определяете функцию, Python запоминает её, но не выполняет код внутри сразу. Код выполняется только тогда, когда вы вызываете(call) функцию, написав её имя, за которым следуют круглые скобки: greet().

Соглашения об именовании функций

Имена функций подчиняются тем же правилам, что и имена переменных (как мы изучали в Главе 3):

  • Используйте строчные буквы
  • Разделяйте слова подчёркиваниями (snake_case)
  • Начинайте с буквы или подчёркивания, а не с цифры
  • Используйте описательные имена, которые показывают, что делает функция
python
# Хорошие имена функций
def calculate_total():
    pass
 
def get_user_age():
    pass
 
def display_menu():
    pass
 
# Плохие имена функций (но синтаксически допустимые)
def x():  # Неописательное
    pass
 
def CalculateTotal():  # Следует использовать строчные буквы
    pass
 
def calc():  # Слишком сокращено
    pass

Примечание: Здесь мы используем pass как заглушку (как мы изучали в Главе 8). Он ничего не делает, но позволяет определению функции быть синтаксически завершённым.

Функции могут содержать любой код

Тело функции может содержать любые операторы Python, которые вы уже изучили: присваивания переменных, условия(conditionals), циклы(loops) и даже вызовы других функций.

python
def check_temperature():
    temperature = 72
    if temperature > 75:
        print("It's warm.")
    elif temperature > 60:
        print("It's comfortable.")
    else:
        print("It's cool.")
 
check_temperature()

Output:

It's comfortable.

Несколько определений функций

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

python
def morning_greeting():
    print("Good morning!")
 
def evening_greeting():
    print("Good evening!")
 
# Вызов каждой функции
morning_greeting()
evening_greeting()

Output:

Good morning!
Good evening!

Порядок определения функций

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

python
# WARNING: This will cause a NameError - for demonstration only
# PROBLEM: Function called before it's defined
say_hello()  # NameError: name 'say_hello' is not defined
 
def say_hello():
    print("Hello!")

Правильный порядок — сначала определить, затем вызвать:

python
# Correct: Define first
def say_hello():
    print("Hello!")
 
# Then call
say_hello()

Output:

Hello!

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

python
def first_function():
    print("First function")
    second_function()  # Это нормально — вызывается во время выполнения
 
def second_function():
    print("Second function")
 
# Обе функции определены до того, как мы вызовем первую
first_function()

Output:

First function
Second function

Функции создают локальную область видимости

Переменные, созданные внутри функции, существуют только в пределах этой функции. Это называется локальной областью видимости(local scope) (мы подробно рассмотрим это в Главе 21). Пока что поймите, что всё, что происходит внутри функции, остаётся внутри функции:

python
def create_message():
    message = "This is local"
    print(message)
 
create_message()
 
# Это вызвало бы ошибку:
# print(message)  # NameError: name 'message' is not defined

Output:

This is local

Переменная message существует только пока выполняется функция. Как только функция завершится, переменная исчезает.

Пустые функции с pass

Иногда вы хотите определить структуру функции, но реализовать её позже. Используйте pass как заглушку:

python
def future_feature():
    pass  # TODO: Реализовать это позже
 
# Функция существует и может быть вызвана, но ничего не делает
future_feature()  # Выполняется без ошибки, ничего не делает

Это полезно, когда вы набрасываете структуру программы, прежде чем заполнять детали.

19.3) Вызов функций и передача аргументов

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

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

Прежде чем продолжить, проясним два термина, которые часто путают:

  • Параметр(parameter): имя переменной в определении функции, которое будет получать значение
  • Аргумент(argument): фактическое значение, которое вы передаёте функции при вызове
python
def greet(name):  # 'name' — параметр
    print(f"Hello, {name}!")
 
greet("Alice")  # "Alice" — аргумент

Output:

Hello, Alice!

Думайте о параметрах как о заполнителях, а об аргументах — как о фактических данных, которые заполняют эти заполнители.

Определение функций с параметрами

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

python
def greet_person(name):
    print(f"Hello, {name}!")
    print("Nice to meet you.")
 
# Вызов с разными аргументами
greet_person("Alice")
print()  # Пустая строка для читабельности
greet_person("Bob")

Output:

Hello, Alice!
Nice to meet you.
 
Hello, Bob!
Nice to meet you.

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

Несколько параметров

Функции могут принимать несколько параметров, разделённых запятыми:

python
def calculate_rectangle_area(length, width):
    area = length * width
    print(f"A rectangle with length {length} and width {width}")
    print(f"has an area of {area} square units.")
 
calculate_rectangle_area(5, 3)
print()
calculate_rectangle_area(10, 7)

Output:

A rectangle with length 5 and width 3
has an area of 15 square units.
 
A rectangle with length 10 and width 7
has an area of 70 square units.

При вызове функции с несколькими параметрами порядок имеет значение. Первый аргумент соответствует первому параметру, второй аргумент — второму параметру, и так далее. Это называется позиционные аргументы(positional arguments).

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

С позиционными аргументами Python сопоставляет аргументы параметрам на основе их позиции:

python
def describe_pet(animal_type, pet_name):
    print(f"I have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name}.")
 
describe_pet("dog", "Buddy")
print()
describe_pet("cat", "Whiskers")

Output:

I have a dog.
My dog's name is Buddy.
 
I have a cat.
My cat's name is Whiskers.

Если перепутать порядок, вы получите неожиданные результаты:

python
def describe_pet(animal_type, pet_name):
    print(f"I have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name}.")
 
# Аргументы в неправильном порядке
describe_pet("Buddy", "dog")

Output:

I have a Buddy.
My Buddy's name is dog.

Технически это корректный Python, но он выдаёт бессмысленный вывод, потому что аргументы стоят не на своих позициях.

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

Чтобы избежать ошибок, связанных с позицией, вы можете использовать именованные аргументы(keyword arguments), явно указывая имена параметров при вызове функции:

python
def describe_pet(animal_type, pet_name):
    print(f"I have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name}.")
 
# Использование именованных аргументов — порядок не важен
describe_pet(animal_type="dog", pet_name="Buddy")
print()
describe_pet(pet_name="Whiskers", animal_type="cat")

Output:

I have a dog.
My dog's name is Buddy.
 
I have a cat.
My cat's name is Whiskers.

С именованными аргументами порядок не важен, потому что Python сопоставляет аргументы параметрам по имени, а не по позиции.

Смешивание позиционных и именованных аргументов

Вы можете смешивать позиционные и именованные аргументы в одном вызове функции, но позиционные аргументы должны идти первыми:

python
def create_profile(username, email, age):
    print(f"Username: {username}")
    print(f"Email: {email}")
    print(f"Age: {age}")
 
# Смешивание позиционных и именованных аргументов
create_profile("alice123", email="alice@example.com", age=25)

Output:

Username: alice123
Email: alice@example.com
Age: 25

Однако вы не можете указывать позиционные аргументы после именованных аргументов:

python
# WARNING: This will cause a SyntaxError - for demonstration only
# PROBLEM: Positional argument after keyword argument
# create_profile(username="alice123", "alice@example.com", 25)
# SyntaxError: positional argument follows keyword argument

Количество аргументов должно совпадать

Когда вы вызываете функцию, вы должны предоставить правильное количество аргументов (если только у функции нет значений по умолчанию, которые мы рассмотрим в Главе 20):

python
def add_numbers(a, b):
    result = a + b
    print(f"{a} + {b} = {result}")
 
add_numbers(5, 3)  # Правильно: 2 аргумента для 2 параметров

Output:

5 + 3 = 8

Передача слишком малого или слишком большого количества аргументов вызывает ошибку:

python
# WARNING: These will cause TypeErrors - for demonstration only
 
# PROBLEM: Too few arguments
# add_numbers(5)
# TypeError: add_numbers() missing 1 required positional argument: 'b'
 
# PROBLEM: Too many arguments
# add_numbers(5, 3, 2)
# TypeError: add_numbers() takes 2 positional arguments but 3 were given

Использование выражений в качестве аргументов

Аргументы не обязательно должны быть простыми значениями — вы можете использовать любое выражение:

python
def display_total(price, quantity):
    total = price * quantity
    print(f"Total cost: ${total:.2f}")
 
# Использование выражений в качестве аргументов
base_price = 10
display_total(base_price * 1.1, 5)  # Цена с наценкой 10%
display_total(15 + 5, 3 * 2)        # Оба аргумента — выражения

Output:

Total cost: $55.00
Total cost: $120.00

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

Вызов функций изнутри функций

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

Вот пример с вычислением площади комнаты:

python
def calculate_area(length, width):
    return length * width
 
def display_room_info(room_name, length, width):
    area = calculate_area(length, width)
    print(f"Room: {room_name}")
    print(f"Dimensions: {length} x {width}")
    print(f"Area: {area} square feet")
 
display_room_info("Living Room", 15, 12)

Output:

Room: Living Room
Dimensions: 15 x 12
Area: 180 square feet

Примечание: Здесь мы используем return, который подробно рассмотрим в следующем разделе. Пока что поймите, что calculate_area() отправляет свой результат обратно в вызывающую функцию.

Вот ещё один пример, показывающий, как функции могут строиться друг на друге — система преобразования температуры:

python
def celsius_to_fahrenheit(celsius):
    return (celsius * 9/5) + 32
 
def format_temperature(fahrenheit):
    return f"{fahrenheit:.1f}°F"
 
def display_temperature_conversion(celsius):
    fahrenheit = celsius_to_fahrenheit(celsius)
    formatted = format_temperature(fahrenheit)
    print(f"{celsius}°C equals {formatted}")
 
# Используйте полную систему преобразования
display_temperature_conversion(25)
display_temperature_conversion(0)
display_temperature_conversion(100)

Output:

25°C equals 77.0°F
0°C equals 32.0°F
100°C equals 212.0°F

В этом примере display_temperature_conversion() вызывает celsius_to_fahrenheit() для преобразования, а затем вызывает format_temperature() для форматирования результата. Каждая функция имеет одну, ясную ответственность, что делает код простым для понимания и сопровождения.

19.4) Использование return для возврата результатов

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

Базовый оператор return

Вот простая функция, которая вычисляет и возвращает значение:

python
def add_numbers(a, b):
    result = a + b
    return result
 
# Сохранить возвращённое значение
sum_value = add_numbers(5, 3)
print(f"The sum is: {sum_value}")

Output:

The sum is: 8

Когда Python встречает оператор return, происходят две вещи:

  1. Функция немедленно прекращает выполнение (любой код после return игнорируется)
  2. Указанное значение отправляется обратно вызывающему коду

Возврат значений напрямую

Вам не нужно сохранять результат в переменной перед возвратом. Можно вернуть выражение напрямую:

python
def multiply(a, b):
    return a * b
 
result = multiply(4, 7)
print(f"4 × 7 = {result}")

Output:

4 × 7 = 28

Это более лаконично и является предпочтительным стилем для простых вычислений.

Использование возвращаемых значений

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

python
def calculate_discount(price, discount_percent):
    discount_amount = price * (discount_percent / 100)
    return discount_amount
 
original_price = 100
discount = calculate_discount(original_price, 20)
 
# Использовать возвращённое значение в вычислениях
final_price = original_price - discount
print(f"Original price: ${original_price:.2f}")
print(f"Discount: ${discount:.2f}")
print(f"Final price: ${final_price:.2f}")

Output:

Original price: $100.00
Discount: $20.00
Final price: $80.00

return немедленно завершает функцию

Когда Python выполняет оператор return, функция немедленно останавливается. Любой код после return никогда не выполняется:

python
def check_age(age):
    if age < 18:
        return "Minor"
    # Эта строка выполняется только если age >= 18
    return "Adult"
 
print(check_age(15))
print(check_age(25))

Output:

Minor
Adult

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

Вот пример, который демонстрирует, как return останавливает выполнение:

python
def process_number(n):
    if n < 0:
        return "Negative"
    print("This line runs for non-negative numbers")
    if n == 0:
        return "Zero"
    print("This line runs for positive numbers")
    return "Positive"
 
print(process_number(-5))
print()
print(process_number(0))
print()
print(process_number(10))

Output:

Negative
 
This line runs for non-negative numbers
Zero
 
This line runs for non-negative numbers
This line runs for positive numbers
Positive

Функции без return

Если в функции нет оператора return, или если в ней есть return без значения, функция возвращает None:

python
def greet(name):
    print(f"Hello, {name}!")
    # Нет оператора return
 
result = greet("Alice")
print(f"The function returned: {result}")

Output:

Hello, Alice!
The function returned: None

Аналогично, «пустой» return (без значения) также возвращает None:

python
def process_data(data):
    if not data:
        return  # Ранний выход, возвращает None
    print(f"Processing: {data}")
    return "Success"
 
result1 = process_data("")
result2 = process_data("some data")
 
print(f"Result 1: {result1}")
print(f"Result 2: {result2}")

Output:

Processing: some data
Result 1: None
Result 2: Success

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

Функции Python могут возвращать несколько значений, разделяя их запятыми. Python автоматически упаковывает их в кортеж(tuple) (как мы изучали в Главе 15):

python
def calculate_rectangle(length, width):
    area = length * width
    perimeter = 2 * (length + width)
    return area, perimeter
 
# Распаковать возвращённый кортеж
rect_area, rect_perimeter = calculate_rectangle(5, 3)
print(f"Area: {rect_area}")
print(f"Perimeter: {rect_perimeter}")

Output:

Area: 15
Perimeter: 16

Вы также можете захватить кортеж как одно значение:

python
def get_student_info():
    name = "Alice"
    age = 20
    grade = "A"
    return name, age, grade
 
# Захватить как кортеж
student = get_student_info()
print(f"Student info: {student}")
print(f"Name: {student[0]}")

Output:

Student info: ('Alice', 20, 'A')
Name: Alice

Возврат разных типов

Функция может возвращать значения разных типов в зависимости от ситуации:

python
def divide(a, b):
    if b == 0:
        return "Error: Division by zero"
    return a / b
 
result1 = divide(10, 2)
result2 = divide(10, 0)
 
print(f"10 / 2 = {result1}")
print(f"10 / 0 = {result2}")

Output:

10 / 2 = 5.0
10 / 0 = Error: Division by zero

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

19.5) Документирование функций с помощью docstrings

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

Что такое docstring?

Docstring(docstring) — это строковый литерал, который появляется как первый оператор в функции (или модуле, классе или методе). Он описывает, что делает функция, какие параметры она принимает и что возвращает. Docstring заключаются в тройные кавычки (""" или '''), что позволяет им занимать несколько строк.

python
def calculate_area(length, width):
    """Calculate the area of a rectangle.
    
    Takes the length and width of a rectangle and returns the area.
    """
    return length * width

Почему docstrings важны

Docstrings служат нескольким важным целям:

  1. Самодокументирование: они объясняют, что делает ваша функция, не требуя от читателя анализировать код
  2. Поддержка IDE: многие инструменты разработки показывают docstring как подсказки, когда вы используете функцию
  3. Функция help(): встроенная функция Python help() отображает docstring
  4. Профессиональная практика: хорошо документированный код проще сопровождать и делиться им с другими

Базовый формат docstring

Для простых функций достаточно однострочного docstring:

python
def greet(name):
    """Print a personalized greeting."""
    print(f"Hello, {name}!")
 
# Доступ к docstring
print(greet.__doc__)

Output:

Print a personalized greeting.

Docstring должен быть кратким описанием того, что делает функция, написанным как команда («Calculate...», «Return...», «Print...»), а не как описание («This function calculates...»).

Многострочные docstring

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

  • Краткое резюме на первой строке
  • Пустую строку
  • Более подробное описание
  • Информацию о параметрах
  • Информацию о возвращаемых значениях
python
def calculate_discount(price, discount_percent):
    """Calculate the discounted price.
    
    Takes an original price and a discount percentage, then returns
    the amount of discount that should be applied.
    
    Parameters:
    price (float): The original price before discount
    discount_percent (float): The discount percentage (0-100)
    
    Returns:
    float: The discount amount in the same currency as the price
    """
    return price * (discount_percent / 100)
 
# Используйте help() чтобы увидеть полный docstring
help(calculate_discount)

Output:

Help on function calculate_discount in module __main__:
 
calculate_discount(price, discount_percent)
    Calculate the discounted price.
    
    Takes an original price and a discount percentage, then returns
    the amount of discount that should be applied.
    
    Parameters:
    price (float): The original price before discount
    discount_percent (float): The discount percentage (0-100)
    
    Returns:
    float: The discount amount in the same currency as the price

Соглашения для docstring

В Python существуют установленные соглашения для написания docstring (описанные в PEP 257). Вот ключевые рекомендации:

1. Используйте тройные двойные кавычки: """docstring"""

python
def good_example():
    """This follows the convention."""
    pass
 
def also_valid():
    '''This works but is less common.'''
    pass

2. Однострочные docstring должны помещаться в одну строку:

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

3. Многострочные docstring должны иметь строку-резюме, затем пустую строку:

python
def process_order(order_id, items):
    """Process a customer order and update inventory.
    
    This function validates the order, checks inventory availability,
    calculates the total cost, and updates the inventory database.
    
    Parameters:
    order_id (str): Unique identifier for the order
    items (list): List of item dictionaries with 'product' and 'quantity'
    
    Returns:
    dict: Order summary with 'total', 'status', and 'confirmation_number'
    """
    # Реализация функции здесь
    pass

Описание параметров и возвращаемых значений

При документировании параметров и возвращаемых значений будьте конкретны относительно:

  • Имена параметров: должны совпадать с фактическими именами параметров в функции
  • Типы: какой тип данных ожидается (мы узнаем о подсказках типов(type hints) в Главе 43)
  • Назначение: для чего используется параметр
  • Возвращаемое значение: что возвращает функция и при каких условиях
python
def find_student(student_id, students):
    """Find a student by ID in a list of student records.
    
    Parameters:
    student_id (int): The unique ID number of the student to find
    students (list): List of student dictionaries, each containing 'id' and 'name'
    
    Returns:
    dict: The student dictionary if found, None if not found
    """
    for student in students:
        if student['id'] == student_id:
            return student
    return None

Docstring для функций с несколькими типами возвращаемых значений

Когда функция может возвращать разные типы в зависимости от ситуации, документируйте все варианты:

python
def safe_divide(a, b):
    """Divide two numbers with error handling.
    
    Parameters:
    a (float): The dividend
    b (float): The divisor
    
    Returns:
    float: The quotient if division is successful
    str: An error message if b is zero
    """
    if b == 0:
        return "Error: Cannot divide by zero"
    return a / b

Доступ к docstring

Вы можете получить доступ к docstring функции тремя способами:

1. Используя атрибут __doc__:

python
def example():
    """This is an example function."""
    pass
 
print(example.__doc__)

Output:

This is an example function.

2. Используя функцию help():

python
def calculate_bmi(weight, height):
    """Calculate Body Mass Index.
    
    Parameters:
    weight (float): Weight in kilograms
    height (float): Height in meters
    
    Returns:
    float: BMI value
    """
    return weight / (height ** 2)
 
help(calculate_bmi)

Output:

Help on function calculate_bmi in module __main__:
 
calculate_bmi(weight, height)
    Calculate Body Mass Index.
    
    Parameters:
    weight (float): Weight in kilograms
    height (float): Height in meters
    
    Returns:
    float: BMI value

3. В интерактивных средах разработки: большинство IDE и редакторов кода отображают docstring как подсказки, когда вы наводите курсор или вводите имя функции.

Когда писать docstring

Вам следует писать docstring для:

  • Всех публичных функций: функций, предназначенных для использования другими частями вашей программы или другими программистами
  • Сложных функций: любой функции, чьё назначение или поведение не очевидны сразу из её имени и параметров
  • Функций с неочевидными параметрами: когда имена параметров сами по себе не полностью объясняют, какие значения ожидаются

Вы можете пропустить docstring для:

  • Очень простых, очевидных функций: функций вроде def add(a, b): return a + b, где имя и параметры делают назначение кристально ясным
  • Приватных вспомогательных функций: небольших внутренних функций, используемых только внутри более крупной функции (хотя даже для них полезны краткие docstring)

Docstring — это не комментарии

Помните, что docstring служат другой цели, чем комментарии:

  • Docstring: описывают, что делает функция и как ею пользоваться (интерфейс)
  • Комментарии: объясняют, как код работает внутри (реализация)
python
def calculate_grade(score, total):
    """Calculate the percentage grade from a score.
    
    Parameters:
    score (int): Points earned
    total (int): Total points possible
    
    Returns:
    float: The percentage grade (0-100)
    """
    # Избегаем деления на ноль
    if total == 0:
        return 0.0
    
    # Вычисляем процент и округляем до 2 знаков после запятой
    percentage = (score / total) * 100
    return round(percentage, 2)

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

Формирование хороших привычек документирования

Написание понятных docstring — это привычка, которая окупается:

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

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

© 2025. Primesoft Co., Ltd.
support@primesoft.ai