Как получить доступ к БЕСПЛАТНОЙ переменной функции извне

Давайте рассмотрим, что у нас есть функция и внутренняя функция, подобная этой (которую мы не можем изменить):

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'>
Другие вопросы по тегам