У вас есть несколько вариантов. Во-первых, обратите внимание, что g в вашем примере на самом деле не является локальным для функции (т.е. не назначен внутри нее), это является глобальным (т.е. не был назначен локальной переменной). Это означает, что он будет найден в модуле, в котором определена функция. Это удачно, поскольку нет никакого способа изменить локальные переменные извне (кроме исправления байт-кода), поскольку они назначаются при запуске функции, а не до. 1001 *
Один из вариантов - просто внедрить вашу функцию в пространство имен модуля функции. Это будет работать, но повлияет на каждую функцию в этом модуле, которая обращается к переменной, а не только на одну функцию.
Чтобы повлиять только на одну функцию, вам нужно вместо этого указать func_globals где-то еще. К сожалению, это свойство только для чтения, но вы можете делать все, что хотите, воссоздав функцию с тем же телом, но с другим глобальным пространством имен:
import new
f = new.function(f.func_code, {'g': my_g_function}, f.func_name, f.func_defaults, f.func_closure)
f теперь будет идентичным, за исключением того, что будет искать глобальные переменные в предоставленном dict. Обратите внимание, что это перепутывает все глобальное пространство имен - если есть переменные, которые f просматривает , убедитесь, что вы также предоставили их. Это также довольно забавно и может не работать на версиях python, отличных от cpython.