如何在python中检查一行是否是一个有效的函数调用?

wot*_*nii 2 python regex parsing string-operations

背景:我正在为ipython创建一个魔术线.这种魔法只适用于行,其中函数的返回值被赋给变量.

我正在寻找一种方法来确保一行是python中有效的函数调用+赋值.

例如,接受以下内容:

a = b()
a,b = c(d,e="f")
a = b(c()+c)
Run Code Online (Sandbox Code Playgroud)

以下内容将被拒绝:

a = def fun() # no function call
b(a=2) # no assignment
a = b + c # no function call 
a = b() + c() # top-level on right-hand-side must be function call
Run Code Online (Sandbox Code Playgroud)

如果该行根本不是有效的python,我不关心它是否通过,因为这将在另一个阶段处理.

Kev*_*vin 7

您可以使用Python自己的解析器(可通过ast模块访问)直接检查每个语句,看它是否是一个右侧是调用的赋值.

import ast

def is_call_assignment(line):
    try:
        node = ast.parse(line)
    except SyntaxError:
        return False
    if not isinstance(node, ast.Module):
        return False
    if len(node.body) != 1 or not isinstance(node.body[0], ast.Assign):
        return False
    statement = node.body[0]
    return isinstance(statement.value, ast.Call)


test_cases = [
    'a = b()',
    'a,b = c(d,e="f")',
    'a = b(c()+c)',
    'a = def fun()',
    'b(a=2)',
    'a = b + c',
    'a = b() + c()'
]

for line in test_cases:
    print(line)
    print(is_call_assignment(line))
    print("")
Run Code Online (Sandbox Code Playgroud)

结果:

a = b()
True

a,b = c(d,e="f")
True

a = b(c()+c)
True

a = def fun()
False

b(a=2)
False

a = b + c
False

a = b() + c()
False
Run Code Online (Sandbox Code Playgroud)