Как получить доступ к БЕСПЛАТНОЙ переменной функции извне
Давайте рассмотрим, что у нас есть функция и внутренняя функция, подобная этой (которую мы не можем изменить):
from functools import wraps
def outer_f(some_callable):
def inner_f(v):
return some_callable(v) + 1
return inner_f
И мы получаем только функцию 'func', которая является вызываемой версией external_f, которая соответствует inner_f следующим образом:
>>> func = outer_f(int)
В таком случае переменная с именем 'some_callable' является типом int, и если мы вызываем func с параметром, мы получаем ответ, подобный следующему:
>>> func('1')
2
Я хотел бы получить доступ к some_callable извне функции, когда у меня есть только экземпляр функции func (что означает, что после external_f вызывается).
Если я не ошибаюсь, some_callable является бесплатной переменной функции inner_f (func.func_code.co_freevars). Как я могу узнать, что func вызывается с параметром int, а только смотрит на func?
Я не смог решить проблему с помощью модуля осмотра или просмотра атрибутов функции. Такие методы, как вызов func с помощью модуля trace, затем проверка трассировки стека или использование pdb, кажутся многообещающими, но они были бы уродливыми хакерами.
Этот вопрос просто сводится к доступу к свободной переменной области действия функции извне.
Итак, как я могу узнать, что свободная переменная 'some_callable' является 'int' без выполнения функции?
1 ответ
Ты можешь сделать:
import inspect
result = inspect.getclosurevars(func).nonlocals['some_callable']
Пример:
>>> from functools import wraps
>>>
>>> def outer_f(some_callable):
... def inner_f(v):
... return some_callable(v) + 1
... return inner_f
...
>>>
>>> func = outer_f(int)
>>>
>>> import inspect
>>> result = inspect.getclosurevars(func).nonlocals['some_callable']
>>>
>>> result
<class 'int'>