假设我有一个如下定义的Python函数:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
我可以使用foo.func_name获取函数的名称。我如何通过编程获得它的源代码,就像我上面键入的那样?
假设我有一个如下定义的Python函数:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
我可以使用foo.func_name获取函数的名称。我如何通过编程获得它的源代码,就像我上面键入的那样?
当前回答
inspect模块有从python对象中检索源代码的方法。但是,似乎只有当源文件位于文件中时,它才有效。如果你有这个,我猜你就不需要从对象中获取源了。
下面使用Python 3.6测试inspect.getsource(foo):
import inspect
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
source_foo = inspect.getsource(foo) # foo is normal function
print(source_foo)
source_max = inspect.getsource(max) # max is a built-in function
print(source_max)
这是第一次印刷:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
然后在inspect.getsource(max)上失败,并出现以下错误:
TypeError: <built-in function max> is not a module, class, method, function, traceback, frame, or code object
其他回答
由于这篇文章被标记为另一篇文章的副本,我在这里回答“lambda”情况,尽管OP不是关于lambdas的。
因此,对于没有在自己的行中定义的lambda函数:除了marko。在ristin的回答中,您可能希望使用mini-lambda或使用此回答中建议的SymPy。
Mini-lambda更轻,支持任何类型的操作,但只适用于单个变量 SymPy更重,但配备了更多的数学/微积分运算。特别是它可以简化你的表达。它还支持同一个表达式中的多个变量。
下面是使用mini-lambda的方法:
from mini_lambda import x, is_mini_lambda_expr
import inspect
def get_source_code_str(f):
if is_mini_lambda_expr(f):
return f.to_string()
else:
return inspect.getsource(f)
# test it
def foo(arg1, arg2):
# do something with args
a = arg1 + arg2
return a
print(get_source_code_str(foo))
print(get_source_code_str(x ** 2))
它会正确地产生
def foo(arg1, arg2):
# do something with args
a = arg1 + arg2
return a
x ** 2
详见mini-lambda文档。顺便说一下,我是作者;)
如果您自己严格地定义了函数,并且它是一个相对较短的定义,那么没有依赖关系的解决方案将是在字符串中定义函数,并将表达式的eval()赋值给您的函数。
如。
funcstring = 'lambda x: x> 5'
func = eval(funcstring)
然后可选地将原始代码附加到函数:
func.source = funcstring
扩展一下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模块有从python对象中检索源代码的方法。但是,似乎只有当源文件位于文件中时,它才有效。如果你有这个,我猜你就不需要从对象中获取源了。
下面使用Python 3.6测试inspect.getsource(foo):
import inspect
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
source_foo = inspect.getsource(foo) # foo is normal function
print(source_foo)
source_max = inspect.getsource(max) # max is a built-in function
print(source_max)
这是第一次印刷:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
然后在inspect.getsource(max)上失败,并出现以下错误:
TypeError: <built-in function max> is not a module, class, method, function, traceback, frame, or code object
如果函数来自文件系统中可用的源文件,那么inspect.getsource(foo)可能会有帮助:
如果foo被定义为:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
然后:
import inspect
lines = inspect.getsource(foo)
print(lines)
返回:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
但我相信,如果函数是从字符串、流或从编译文件导入的,那么你就不能检索它的源代码。