Проверьте код объекта фрейма co_freevars
, который является кортежем имен переменных замыкания, которые использует объект кода:
def is_nonlocal(frame, varname):
return varname in frame.f_code.co_freevars
Обратите внимание, что это переменные замыкания, тип переменных, которыеnonlocal
заявление ищет.Если вы хотите включить все переменные, которые не являются локальными, вы должны проверить co_varnames
(локальные переменные не используются во внутренних областях) и co_cellvars
(локальные переменные, используемые во внутренних областях):
def isnt_local(frame, varname):
return varname not in (frame.f_code.co_varnames + frame.f_code.co_cellvars)
Кроме того, не путайте вещи с co_names
, который в настоящее время неверно документирован.В inspect
документах сказано, что co_names
для локальных переменных, но co_names
является своего рода корзиной «всего остального».Он включает в себя глобальные имена, имена атрибутов и несколько видов имен, участвующих в импорте - в основном, если ожидается, что для выполнения действительно потребуется строковая форма имени, он указывается в co_names
.