Предположим, у меня есть функция Python, как определено ниже:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
Я могу получить имя функции, используя foo.func_name
. Как я могу программно получить его исходный код, как я напечатал выше?
foo.__name__
Ответы:
Если функция из исходного файла, доступного в файловой системе, то
inspect.getsource(foo)
может помочь:Если
foo
определяется как:Затем:
Возвращает:
Но я считаю, что если функция скомпилирована из строки, потока или импортирована из скомпилированного файла, то вы не сможете получить ее исходный код.
источник
len
. Где я могу найти исходный кодlen
функции?inspect.getsourcelines(foo)
Модуль inspect имеет методы для извлечения исходного кода из объектов Python. По-видимому, это работает только в том случае, если источник находится в файле. Если бы у вас было это, я думаю, вам не нужно было бы получать источник от объекта.
источник
python 3.5.3
интерпретаторе.import inspect
+inspect.getsource(foo)
работал нормально.dis
Ваш друг, если исходный код недоступен:источник
Если вы используете IPython, то вам нужно набрать "foo ??"
источник
dir(MyClass)
затемMyClass.__init__??
и так далее.Хотя я в целом согласен, что
inspect
это хороший ответ, я не согласен с тем, что вы не можете получить исходный код объектов, определенных в интерпретаторе. Если вы используетеdill.source.getsource
изdill
, вы можете получить источник функций и лямбд, даже если они определены в интерактивном режиме. Он также может получить код для связанных или несвязанных методов и функций класса, определенных в карри ... однако вы не сможете скомпилировать этот код без кода вмещающего объекта.источник
dill.source.getsource
проверяет историю интерпретатора для функций, классов, лямбд и т. д. - он не проверяет содержимое строк, переданных в exec.dill
для ответа на этот вопрос: stackoverflow.com/questions/13827543/…dill.source
имеет такие функции, какgetname
и,importable
иgetsource
которые направлены на получение исходного кода (или импортируемого, который возвращает объект) для любого данного объекта. Для простых вещей , какint
нет нет источника, так что это не работает , как ожидалось (т.е. «а = 10» возвращает «10»).>>> a = 10; print( [key for key, val in globals().items() if val is a][0] )
dill
, но мой ответ оставляет желать лучшего (IE, если у вас есть несколько имен для одного и того же значения, он не может выяснить, какое использовалось. Если вы передать выражение, оно не может сказать, что это было за выражение. Черт, если вы передадите выражение, которое соответствует имени, оно даст это имя вместо этого.) Можетdill
устранить любой из этих недостатков моего ответа здесь: stackoverflow.com/a/28634996/901641Чтобы расширить ответ Руны:
РЕДАКТИРОВАТЬ: Как указывает @ 0sh, этот пример работает,
ipython
но не простойpython
. Однако при импорте кода из исходных файлов все должно быть хорошо.источник
getsource(foo)
.Вы можете использовать
inspect
модуль, чтобы получить полный исходный код для этого. Вы должны использоватьgetsource()
метод для этого изinspect
модуля. Например:Вы можете проверить это больше вариантов по ссылке ниже. получить ваш код Python
источник
Поскольку этот пост помечен как дубликат этого другого поста , я отвечу здесь за случай «лямбда», хотя ОП не касается лямбд.
Таким образом, для лямбда-функций, которые не определены в своих собственных строках: в дополнение к ответу marko.ristin вы можете использовать мини-лямбду или SymPy, как предложено в этом ответе .
mini-lambda
легче и поддерживает любые операции, но работает только для одной переменнойSymPy
тяжелее, но гораздо больше оснащено математическими / вычислительными операциями. В частности, это может упростить ваши выражения. Он также поддерживает несколько переменных в одном выражении.Вот как вы можете сделать это, используя
mini-lambda
:Это правильно дает
Смотрите
mini-lambda
документацию для деталей. Я, кстати, автор;)источник
Пожалуйста, обратите внимание, что принятые ответы работают, только если лямбда дана в отдельной строке. Если вы передадите его в качестве аргумента функции и захотите получить лямбда-код в виде объекта, проблема будет немного хитрой, поскольку
inspect
даст вам всю строку.Например, рассмотрим файл
test.py
:Выполнение этого дает вам (помните абзац!):
Чтобы получить исходный код лямбда-выражения, лучше всего, на мой взгляд, повторно проанализировать весь исходный файл (используя
f.__code__.co_filename
) и сопоставить лямбда-узел AST по номеру строки и ее контексту.Мы должны были сделать именно это в нашей библиотеке конструирования по контракту icontract, поскольку нам пришлось анализировать лямбда-функции, которые мы передаем в качестве аргументов декораторам. Здесь слишком много кода для вставки, так что взгляните на реализацию этой функции .
источник
Если вы строго определяете функцию самостоятельно, и это относительно короткое определение, решение без зависимостей будет состоять в том, чтобы определить функцию в строке и присвоить eval () выражения вашей функции.
Например
затем при желании присоединить исходный код к функции:
источник
обобщить :
источник
Я считаю, что имена переменных не хранятся в файлах pyc / pyd / pyo, поэтому вы не можете получить точные строки кода, если у вас нет исходных файлов.
источник