Как получить исходный код функции Python?
У меня есть функция на Python, определенная следующим образом:
def foo(arg1, arg2):
# что-то делаем с аргументами
a = arg1 + arg2
return a
Я могу получить имя функции, используя foo.func_name. Но как мне программно получить исходный код этой функции, как он указан выше?
5 ответ(ов)
IPython
Примечание: данный ответ актуален только для IPython и проектов, которые его используют, таких как Jupyter.
Вам нужно просто использовать foo?? или ??foo.
Если вы используете IPython, введите foo?? или ??foo, чтобы увидеть полный исходный код функции. Чтобы отобразить только докстроку, используйте foo? или ?foo. Это также работает в Jupyter Notebook.
Пример использования:
In [19]: foo??
Signature: foo(arg1, arg2)
Source:
def foo(arg1,arg2):
# выполнить что-то с аргументами
a = arg1 + arg2
return a
File: ~/Desktop/<ipython-input-18-3174e3126506>
Type: function
dis — ваш друг, если исходный код недоступен.
Вы можете использовать модуль dis для дизассемблирования функции в байт-код, что позволяет вам увидеть, как Python обрабатывает вашу функцию, даже если исходный код недоступен. Например:
>>> import dis
>>> def foo(arg1, arg2):
... # делаем что-то с аргументами
... a = arg1 + arg2
... return a
...
>>> dis.dis(foo)
3 0 LOAD_FAST 0 (arg1)
3 LOAD_FAST 1 (arg2)
6 BINARY_ADD
7 STORE_FAST 2 (a)
4 10 LOAD_FAST 2 (a)
13 RETURN_VALUE
В этом примере мы видим, как функция foo загружает аргументы arg1 и arg2, выполняет операцию сложения и возвращает результат. Используйте dis для изучения работы функций, когда исходный код отсутствует.
Чтобы дополнить ответ runeh:
>>> def foo(a):
... x = 2
... return x + a
>>> import inspect
>>> inspect.getsource(foo)
u'def foo(a):\n x = 2\n return x + a\n'
print inspect.getsource(foo)
def foo(a):
x = 2
return x + a
ПРАВКА: Как указал @0sh, данный пример работает в ipython, но не в обычном python. Тем не менее, он должен корректно работать в обоих случаях при импорте кода из исходных файлов.
Для краткого подведения итогов:
Вы можете использовать модуль inspect, чтобы получить исходный код функции foo. Вот как это сделать:
import inspect
print("".join(inspect.getsourcelines(foo)[0]))
Этот код импортирует модуль inspect, а затем использует функцию getsourcelines, которая возвращает строки исходного кода указанной функции. Мы берем только первую часть возвращаемого значения (список строк) и объединяем его в одну строку с помощью join, чтобы вывести исходный код функции foo в удобочитаемом формате.
Если вы сами строго определяете функцию и определение достаточно короткое, решение без зависимостей может заключаться в том, чтобы определить функцию в виде строки и присвоить результат выполнения eval() этой строке вашей функции.
Например:
funcstring = 'lambda x: x > 5'
func = eval(funcstring)
Также можно дополнительно прикрепить оригинальный код к функции:
func.source = funcstring
Таким образом, вы сможете динамически создавать функции без необходимости использования дополнительных библиотек. Однако имейте в виду, что использование eval() может представлять определенные риски безопасности, если вы работаете с ненадежными источниками.
Как создать декораторы функций и объединить их?
Декораторы с параметрами?
Как вызвать функцию из другого .py файла?
Почему у некоторых функций есть двойные подчеркивания "__" перед и после имени функции?
Следует ли добавлять запятую после последнего аргумента в вызове функции? [закрыто]