TGViewer
Находки в опенсорсе Находки в опенсорсе @opensource_findings · 12.6K subscribers
Post #852 5.59K
Лучший курс по Python 9: Переменные

https://www.youtube.com/watch?v=crSzQKfevZU

Я хотел сделать видео про переменные, которое бы рассказывало: а как на самом деле происходит создание и поиск имени? Все рассказывают про переменные, как про какие "коробки" для значений. А не они не коробки! Потому, в видео про переменные я рассказываю:
- Что никаких переменных в Python – нет 🌚
- Про frame.f_locals и frame.f_globals
- Про генерацию байткода: покрываем все стадии через symtable.c / compile.c / codegen.c
- Про замыкания с .__closure__ и MAKE_CELL
- Ну и про рантайм конечно же! Как работает, например globals() и locals() на самом деле


/*[clinic input]
globals as builtin_globals

Return the dictionary containing the current scope's global variables.

NOTE: Updates to this dictionary *will* affect name lookups in the current
global scope and vice-versa.
[clinic start generated code]*/

static PyObject *
builtin_globals_impl(PyObject *module)
/*[clinic end generated code: output=e5dd1527067b94d2 input=9327576f92bb48ba]*/
{
PyObject *d;

d = PyEval_GetGlobals();
return Py_XNewRef(d);
}


Бонус! Я показывал видео Грише Петрову до публикации. Он дал ценную обратную связь: я не упомянул, почему иногда модификация locals().update() работает, а иногда нет. Исправляюсь!

- locals(), как показано в видео, обычно возвращает новый dict, потому что использует прокси внутри C. Внутри функции модификация locals() работать не будет. И вот почему, код:


// PyObject * _PyEval_GetFrameLocals(void)
if (PyFrameLocalsProxy_Check(locals)) {
PyObject* ret = PyDict_New();
if (ret == NULL) {
Py_DECREF(locals);
return NULL;
}
if (PyDict_Update(ret, locals) < 0) {
Py_DECREF(ret);
Py_DECREF(locals);
return NULL;
}
Py_DECREF(locals);
return ret;
}

assert(PyMapping_Check(locals));
return locals;


На самом деле


def some():
locals().update({'a': 1})
print(a)


будет делать .update на *другом* dict объекте, который мы создали из PyFrameLocalsProxy, а не сам прокси.
И изменения видны не будут.

- А вот тут я пропустил шаг: так а почему на уровне модуля / REPL оно работает?

Потому что в REPL / модуле frame.f_locals is frame.f_globals. Вот код:


static int
PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,
PyCompilerFlags *flags)
{
PyArena *arena = _PyArena_New();
if (arena == NULL) {
return -1;
}

mod_ty mod;
PyObject *interactive_src;
int parse_res = pyrun_one_parse_ast(fp, filename, flags, arena, &mod, &interactive_src);

PyObject *main_module = PyImport_AddModuleRef("__main__");
PyObject *main_dict = PyModule_GetDict(main_module); // borrowed ref

PyObject *res = run_mod(mod, filename, main_dict, main_dict, flags, arena, interactive_src, 1);
// ...


Где


static PyObject *
run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals,
PyCompilerFlags *flags, PyArena *arena, PyObject* interactive_src,
int generate_new_source)
{


- Далее, на слайде я показываю, но повторю данную мысль еще раз:


NOTE: Whether or not updates to this dictionary will affect name lookups in
the local scope and vice-versa is *implementation dependent* and not
covered by any backwards compatibility guarantees.


Не надо так! Не модифицируйте скоупы, просто потому что можно!

Надеюсь, что было интересно.
Поддержать такой контент можно тут:
- https://boosty.to/sobolevn
- https://github.com/sponsors/wemake-services

#lkpp
YouTube Лучший курс по Python 9: Переменные Лучший курс по питону: 9 Или "обзор исходников CPython с CPython core разработчиком". Тема: переменные - Что такое "переменная" в Python? - Есть ли в Python "переменные"? - Чем "переменная" отличается от "имени"? - Что такое `locals()` и `globals()` в Python?…
  • 🔥 57
  • ❤ 19
  • 👍 10
  • 🤔 1
  • 🤯 1
More from @opensource_findings
  1. Sep 28, 2026Еще анонсы докладов на бесплатную конференцию 17 октября в НН Регистрация: https://itgorky…
  2. Sep 25, 2026Монадические выражения в Python. Наконец-то! Продолжаем разговор про интересные PEPы. Пого…
  3. Sep 15, 2026PEPы в Python окончательно вышли из-под контроля Давайте посмотрим, что происходит с ПЕПам…
  4. Sep 10, 2026Большая бесплатная конференция в Нижнем Новгороде 17 октября Регистрация: https://itgorky.…
  5. Sep 1, 2026Post #985
  6. Aug 24, 2026JIT могут удалить из CPython! PEP-836: https://peps.python.org/pep-0836 JIT в CPython имее…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →