threading.local в примере: почему выводится "missing"
@python_quizРазберем этот квиз
Коротко: в примере используется threading.local — отдельное пространство атрибутов для каждого потока. Код создаёт атрибут только в главном потоке, а в новом потоке этот атрибут отсутствует, поэтому используется значение по умолчанию в getattr.
Исходный код

Что здесь происходит — пошагово
- Создаётся объект
store = local(). Это не обычный контейнер атрибутов: у каждого потока у этого объекта своё набор атрибутов. - В основном потоке устанавливается store.x = 'main'. Этот атрибут хранится в пространстве атрибутов именно главного потока.
- Создаётся и запускается новый поток. Он получает тот же объект store, но для него пространство атрибутов пустое (пока что).
- Внутри нового потока вызывается getattr(store, 'x', 'missing'). Поскольку в этом потоке атрибут x не установлен, getattr возвращает заданное значение по умолчанию: 'missing'.
- В результате на вывод идёт строка missing.
Анализ вариантов ответов
- Выведет: main
Поскольку атрибут x был установлен в главном потоке, на первый взгляд кажется, что другой поток может его прочитать. Но threading.local обеспечивает независимые наборы атрибутов для каждого потока, поэтому этот вариант неверен для данного кода.
- Выведет: missing
Этот вариант соответствует тому, что реально произойдёт: в новом потоке атрибут x отсутствует, getattr с третьим аргументом возвращает значение по умолчанию ('missing').
- Выведет: ошибка
AttributeError
Ошибки не возникает, потому что используется getattr с аргументом по умолчанию. Если бы код делал доступ через store.x внутри нового потока без try/except, тогда действительно могла бы появиться AttributeError. Но в данном коде аварии не будет.
- Поведение не определено, может быть main или missing
Поведение детерминировано: threading.local даёт отдельные пространства атрибутов для потоков, так что результат будет predictable — 'missing' при приведённом порядке операций. Нет гонки между созданием атрибута и чтением в другом потоке в данном коде, потому что атрибут устанавливается до старта потока.
Небольшие модификации и демонстрации
Гарантировать, что поток завершился, и увидеть вывод явно:

Если вы хотите, чтобы поток видел значение 'main', нужно передать значение явно или поставить глобальную переменную (не рекомендуется для синхронизации), либо установить атрибут внутри самого потока:

Или использовать общий (не thread-local) контейнер:

Вывод
threading.local создаёт независимые наборы атрибутов для каждого потока. В представленном коде атрибут x установлен только в главном потоке, а чтение в дочернем потоке возвращает значение по умолчанию, указанное в getattr. Для обмена данными между потоками используйте явную передачу значений, общие структуры данных с синхронизацией или другие механизмы межпоточного взаимодействия.