我如何获得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文件中,所以如果你没有源文件的话,你不能检索到确切的代码行。