Как получить исходный код функции 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()
может представлять определенные риски безопасности, если вы работаете с ненадежными источниками.
Как создать декораторы функций и объединить их?
Как получить имя функции в виде строки?
Каковы преимущества использования лямбд? [закрыто]
Как применить функцию к двум столбцам DataFrame в Pandas
Как получить возвращаемое значение из потока?