我如何获得Python函数的源代码?

假设我有一个如下定义的Python函数:

def foo(arg1,arg2): #do something with args a = arg1 + arg2 return a 

我可以使用foo.func_name获取函数的名称。 我如何以编程方式获取其源代码,如上面input的内容?

如果函数来自文件系统上可用的源文件,那么inspect.getsourcelines(foo)可能有帮助:

 >>> import inspect >>> lines = inspect.getsourcelines(foo) >>> print("".join(lines[0])) def foo(arg1,arg2): #do something with args a = arg1 + arg2 return a 

但我相信,如果函数是从一个string,stream编译或从编译的文件导入,则无法检索其源代码。

inspect模块具有从python对象中检索源代码的方法。 看似只有源文件位于文件中才有效。 如果你有这个,我猜你不需要从对象中获取源代码。

如果源代码不可用, dis是你的朋友:

 >>> import dis >>> def foo(arg1,arg2): ... #do something with args ... 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 

虽然我通常会同意inspect是一个很好的答案,但我不同意你不能得到解释器中定义的对象的源代码。 如果您使用dill.source.getsource ,即使它们是交互式定义的,也可以获得函数和lambdaexpression式的源代码。 它也可以从curries中定义的绑定或非绑定类方法和函数获取代码…但是,如果没有包含对象的代码,您可能无法编译该代码。

 >>> from dill.source import getsource >>> >>> def add(x,y): ... return x+y ... >>> squared = lambda x:x**2 >>> >>> print getsource(add) def add(x,y): return x+y >>> print getsource(squared) squared = lambda x:x**2 >>> >>> class Foo(object): ... def bar(self, x): ... return x*x+x ... >>> f = Foo() >>> >>> print getsource(f.bar) def bar(self, x): return x*x+x >>> 

如果你使用的是IPython,那么你需要input“foo ??”

 In [19]: foo?? Signature: foo(arg1, arg2) Source: def foo(arg1,arg2): #do something with args a = arg1 + arg2 return a File: ~/Desktop/<ipython-input-18-3174e3126506> Type: function 

为了扩大runeh的答案:

 >>> def foo(a): ... x = 2 ... return x + a >>> import inspect >>> inspect.getsource(foo) u'def foo(a):\nx = 2\n return x + a\n' print inspect.getsource(foo) def foo(a): x = 2 return x + a 

编辑:正如@ 0sh指出的这个例子工作使用ipython但不是普通的python 。 但是,从源文件导入代码时,两者都应该没问题。

您可以使用inspect模块获取完整的源代码。 您必须使用来自inspect模块的getsource()方法。 例如:

 import inspect def get_my_code(): x = "abcd" return x print(inspect.getsource(get_my_code)) 

您可以在下面的链接中查看更多选项。 检索你的Python代码

总结:

 import inspect print( "".join(inspect.getsourcelines(foo)[0])) 

如果你自己严格定义了函数,而且它是一个相对较短的定义,那么没有依赖关系的解决scheme就是在string中定义函数,并将expression式的eval()赋值给函数。

例如

 funcstring = 'lambda x: x> 5' func = eval(funcstring) 

然后可以select将原始代码附加到该函数:

 func.source = funcstring 

相信variables名不存储在pyc / pyd / pyo文件中,所以如果你没有源文件的话,你不能检索到确切的代码行。