python函数调用位置_解析Python函数调用以获取参数位置

此代码使用ast(用于查找初始参数偏移)和正则表达式(用于标识参数的边界)的组合:

import ast

import re

def collect_offsets(call_string):

def _abs_offset(lineno, col_offset):

current_lineno = 0

total = 0

for line in call_string.splitlines():

current_lineno += 1

if current_lineno == lineno:

return col_offset + total

total += len(line)

# parse call_string with ast

call = ast.parse(call_string).body[0].value

# collect offsets provided by ast

offsets = []

for arg in call.args:

a = arg

while isinstance(a, ast.BinOp):

a = a.left

offsets.append(_abs_offset(a.lineno, a.col_offset))

for kw in call.keywords:

offsets.append(_abs_offset(kw.value.lineno, kw.value.col_offset))

if call.starargs:

offsets.append(_abs_offset(call.starargs.lineno, call.starargs.col_offset))

if call.kwargs:

offsets.append(_abs_offset(call.kwargs.lineno, call.kwargs.col_offset))

offsets.append(len(call_string))

return offsets

def argpos(call_string):

def _find_start(prev_end, offset):

s = call_string[prev_end:offset]

m = re.search('(\(|,)(\s*)(.*?)$', s)

return prev_end + m.regs[3][0]

def _find_end(start, next_offset):

s = call_string[start:next_offset]

m = re.search('(\s*)$', s[:max(s.rfind(','), s.rfind(')'))])

return start + m.start()

offsets = collect_offsets(call_string)

result = []

# previous end

end = 0

# given offsets = [9, 14, 21, ...],

# zip(offsets, offsets[1:]) returns [(9, 14), (14, 21), ...]

for offset, next_offset in zip(offsets, offsets[1:]):

#print 'I:', offset, next_offset

start = _find_start(end, offset)

end = _find_end(start, next_offset)

#print 'R:', start, end

result.append((start, end))

return result

if __name__ == '__main__':

try:

while True:

call_string = raw_input()

positions = argpos(call_string)

for p in positions:

print ' ' * p[0] + '^' + ((' ' * (p[1] - p[0] - 2) + '^') if p[1] - p[0] > 1 else '')

print positions

except EOFError, KeyboardInterrupt:

pass

输出:

whatever(foo, baz(), 'puppet', 24+2, meow=3, *meowargs, **meowargs)

^ ^

^ ^

^ ^

^ ^

^ ^

^ ^

^ ^

[(9, 12), (14, 19), (21, 29), (31, 35), (37, 43), (45, 54), (56, 66)]

f(1, len(document_text) - 1 - position)

^

^ ^

[(2, 3), (5, 38)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值