假设我有一个如下定义的Python函数:
def foo(arg1,arg2): #do something with args a = arg1 + arg2 return a
我可以使用函数的名称foo.func_name
.如上所示,我如何以编程方式获取其源代码?
如果该函数来自文件系统上可用的源文件,那么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
但我相信,如果函数是从字符串,流或从编译文件导入的,那么您无法检索其源代码.
该检查模块具有用于从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
如果你使用的是IPython,那么你需要输入"foo ??"
In [19]: foo?? Signature: foo(arg1, arg2) Source: def foo(arg1,arg2): #do something with args a = arg1 + arg2 return a File: ~/Desktop/Type: function
虽然我一般都认为这inspect
是一个很好的答案,但我不同意你无法获得解释器中定义的对象的源代码.如果使用dill.source.getsource
from dill
,则可以获取函数和lambdas的来源,即使它们是以交互方式定义的.它还可以从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 >>>
为了扩展符文的答案:
>>> 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
模块获取完整的源代码.你必须使用getsource()
方法为从inspect
模块.例如:
import inspect def get_my_code(): x = "abcd" return x print(inspect.getsource(get_my_code))
您可以在以下链接中查看更多选项. 检索你的python代码
由于此帖子被标记为与其他帖子重复,因此我在这里针对“ lambda”案例回答,尽管OP与lambda无关。
因此,对于未在自己的行中定义的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
文档。我是作者;)