使用inspect.getsourcelines
函数,我已经能够获得如下所示的Python函数的源代码:
import inspect
def some_decorator(x):
return x
@some_decorator
def foo():
print("bar")
print(inspect.getsourcelines(foo)[0])
此代码将以列表的形式正确输出函数的源代码行:
['@some_decorator\n', 'def foo():\n', ' print("bar")\n']
但是,我只想要函数内部的代码,而不是整个函数声明。所以我只需要这个输出(还要注意正确的缩进):
['print("bar")\n']
我曾尝试使用一个切片和一个strip
来删除前两行,然后删除缩进,但这对许多函数都不起作用,我必须相信还有更好的方法。
inspect
模块,或者我可以pip install
的其他模块,有这个功能吗?
发布于 2016-06-27 17:53:11
你会发现你想要的代码之前都是空白的,所以你可以试试这个
print filter(lambda x:x.startswith(' '), inspect.getsourcelines(foo)[0])
发布于 2016-06-27 17:59:11
使用re
处理def
和async def
def_regexp = r"^(\s*)(?:async\s+)?def foobar\s*?\:"
def get_func_code(func):
lines = inspect.getsourcelines(foo)[0]
for idx in range(len(lines)): # in py2.X, use range
def_match = re.match(line, def_regexp)
if def_match:
withespace_len = len(def_match.group(1)) # detect leading whitespace
return [sline[whitespace_len:] for sline in lines[idx+1:]]
请注意,这不会处理单行定义。需要在def和包含冒号之后匹配左方括号和右方括号(以避免元组和类型提示)。
原始版本:
只需查找包含def
语句的第一行。
def get_func_code(func):
lines = inspect.getsourcelines(foo)[0]
for idx in range(len(lines)): # in py2.X, use range
if line.lstrip().startswith('def %s' % func.__name__) or\
line.lstrip().startswith('async def %s' % func.__name__): # actually should check for `r"^async\s+def\s+%s" % func.__name__` via re
withespace_len = len(line.split('def'), 1)[0] # detect leading whitespace
return [sline[whitespace_len:] for sline in lines[idx+1:]]
这应该可以安全地处理制表符和空格缩进,即使在混合情况下也是如此。
https://stackoverflow.com/questions/38050649
复制相似问题