课程片段

Функции и аннотации типов в Python: от def до sentinel

def, аргументы по умолчанию, *args и **kwargs, область видимости, аннотации типов. Для опытных: синтаксис дженериков и оператор type (3.12), ленивые аннотации (3.14), встроенный sentinel (3.15).

функция аргументы аннотации типов дженерики sentinel
本节课您将学到
  • Писать функции с понятными аргументами
  • Подписывать типы
  • Использовать sentinel вместо None-заглушек

课程开头

None означал «не передали» — пока кто-то не передал None

  • Аргумент по умолчанию None путает «не указано» и «указано None»
  • Старый обход: _MISSING = object()
  • В 3.15: встроенный sentinel()

Знакомая многим ловушка. Функция получения курса валют принимает значение по умолчанию, и если его не передали, должна выбросить ошибку. По привычке пишут: по умолчанию None. И всё работает — пока коллега не передаст None осознанно, имея в виду «если курса нет, верни пустоту». Функция не может отличить «не передали» от «передали None». Годами это решали самодельной заглушкой. В 3.15 для этого есть встроенный инструмент — дойдём до него в конце.

def get_rate(currency, default=None):
    rate = RATES.get(currency)
    if rate is not None:
        return rate
    if default is None:              # не передали?
        raise KeyError(currency)     # ...или передали None?
    return default

get_rate("XYZ", default=None)   # хотели None, получили KeyError

def: даём куску кода имя

  • def имя(параметры): + тело с отступом
  • return — вернуть результат; без него вернётся None
  • Функция — тоже объект: её можно передать в другую

Функция — это кусок кода с именем, который можно вызвать сколько угодно раз. Объявляем словом def, в скобках перечисляем параметры, после двоеточия с отступом — тело. Слово return отдаёт результат тому, кто вызвал. Если его забыть, функция вернёт пустое значение None — частая причина недоумения у новичков. Хорошее правило: одна функция — одно действие, а имя — глагол, который это действие описывает.

def add_expense(item, amount, category="Прочее"):
    """Создаёт запись о трате."""
    return {"item": item, "amount": amount,
            "category": category}

e = add_expense("Кофе", 250)
print(e)

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

  • Позиционные — по порядку: add("Кофе", 250)
  • Именованные — по имени, порядок не важен
  • Параметр со значением по умолчанию — необязательный

Передать аргументы можно двумя способами. По порядку — тогда первое значение попадёт в первый параметр, второе во второй. Или по имени — тогда порядок неважен, а вызов читается как фраза: сумма триста, категория «Транспорт». Именованные аргументы особенно выручают, когда параметров много или среди них есть логические флажки. Согласитесь, «включить архив равно истина» читается куда понятнее, чем загадочное True пятым по счёту.

add_expense("Такси", 300, "Транспорт")       # по порядку

add_expense(amount=300,                      # по имени
            item="Такси",
            category="Транспорт")

# смешанно: сначала позиционные, потом именованные
add_expense("Такси", 300, category="Транспорт")

完整课程需订阅

完整版还有 10 张幻灯片。

登录并订阅后,即可观看视频、查看全部幻灯片、笔记、测试、AI 导师和面试。

登录或注册 订阅

课程内容

  1. None означал «не передали» — пока кто-то не передал None
  2. def: даём куску кода имя
  3. Позиционные и именованные аргументы
  4. *args и **kwargs: сколько угодно аргументов
  5. Грабли: список по умолчанию живёт вечно
  6. Область видимости: LEGB
  7. Аннотации типов: подсказки, а не проверки
  8. ❓ Стоп-проверка: что вернёт эта функция?
  9. ✅ Ответ: None — забыли return
  10. Что нового: дженерики без TypeVar (3.12, PEP 695)
  11. Что нового: ленивые аннотации (3.14, PEP 649)
  12. Что нового: встроенный sentinel (3.15, PEP 661)
  13. Итог: трекер разбит на функции с типами

本课时相关文章

本课程全部课程

  1. Python 3.15 с нуля и для опытных: что нового и как учить
  2. Python 3.15: установка, REPL и первый скрипт за десять минут
  3. Переменные, числа и строки в Python: f-строки и t-строки
  4. Условия, циклы и match/case в Python: управляем ходом программы
  5. Списки, кортежи, словари и множества: frozendict в Python 3.15
  6. Comprehensions в Python: распаковка * и ** внутри (PEP 798)
  7. Функции и аннотации типов в Python: от def до sentinel
  8. Ошибки и исключения в Python 3.15: читаем трейсбек и подсказки «Did you mean»
  9. Модули, пакеты и ленивые импорты в Python 3.15 (PEP 810)
  10. Файлы, JSON и CSV в Python: pathlib и UTF-8 по умолчанию
  11. Классы и dataclasses в Python: ООП без лишнего кода
  12. Асинхронность и потоки в Python: asyncio, TaskGroup и free-threading
  13. Профилирование Python 3.15: Tachyon вместо cProfile и итоговый проект