Получение функции Python для объекта кода

Функция Python имеет объект кода __code__.

A sys.settrace trace frame имеет объект кода f_code.

Для вызовов вызовов, которые являются функциями, как я могу получить объект функции (и его член __annotation__)?

До сих пор, в результате проб и ошибок, я:

if hasattr(frame.f_globals.get(frame.f_code.co_name),"__annotations__"):

Это, похоже, работает для функций, но не для функций класса; Хуже того, он смешивает функции-члены класса с функциями верхнего уровня с тем же именем.

(Я на Python 3.2.3 (Xubuntu). Я вижу, что модуль Python 3.3 inspect имеет функцию signature, это вернет аннотация для объекта кода или ему тоже нужен объект функции?)

Ответ 1

Через модуль inspect.getframeinfo. Я имею в виду - нет простого способа сделать это в Python. В большинстве случаев вы можете получить объект кода, не имея уже функции, это через фрост-интроспекцию.

Осмотр функции getframeinfo возвращает некоторую информацию о запущенном кадре, затем вы можете получить объект функции, получив его имя.

Жестко это зависит от реализации и имеет некоторые недостатки:

>>> import inspect
>>> def a():
...   return inspect.currentframe()
... 

>>> inspect.getframeinfo(a())
Traceback(filename='<stdin>', lineno=2, function='a', code_context=None, index=None)
>>> b = inspect.getframeinfo(a())
>>> b.function
'a'

Другим способом, но зависимым от реализации, является использование gc-модуля (сборщика мусора) для получения ссылок на указанный объект кода.

>>> import gc
>>> from types import FunctionType
>>> def a(): pass
... 
>>> code = a.__code__

>>> [obj for  obj in  gc.get_referrers(code) if isinstance(obj, FunctionType)  ][0]
<function a at 0x7f1ef4484500>
>>> 

- Это для Python 3 - для Python 2 нужно заменить __code__ на func_code