Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python中检查一行是否是有效的函数调用?_Python_Regex_Parsing_String Operations - Fatal编程技术网

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

如何在python中检查一行是否是有效的函数调用?,python,regex,parsing,string-operations,Python,Regex,Parsing,String Operations,背景:我目前正在为ipython创建一个线条魔术。这种魔术只适用于函数返回值被指定给变量的行 我正在寻找一种方法来确保在python中一行是有效的函数调用+赋值 e、 g.应接受以下内容: a = b() a,b = c(d,e="f") a = b(c()+c) 以下情况应予以拒绝: a = def fun() # no function call b(a=2) # no assignment a = b + c # no function call a = b() + c() # top

背景:我目前正在为ipython创建一个线条魔术。这种魔术只适用于函数返回值被指定给变量的行

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

e、 g.应接受以下内容:

a = b()
a,b = c(d,e="f")
a = b(c()+c)
以下情况应予以拒绝:

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

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

我想到的最好的办法是:

  • 应用此regexp [A-z, ]*= *[A-z_]* *\(.*\) 第3步也有点像这样:

    def matched(str):
        count = 0
        for i in str.strip():
            if i == "(":
                count += 1
            elif i == ")":
                count -= 1
            if count < 0 or (count < 1 and i>=len(str)-1):
                return False
        return count == 0
    
    def匹配(str):
    计数=0
    对于str.strip()中的i:
    如果i==“(”:
    计数+=1
    elif i==”):
    计数-=1
    如果计数<0或(计数<1且i>=len(str)-1):
    返回错误
    返回计数==0
    
    (基于)

    这个解决方案非常丑陋,因为如果顶层没有函数调用,我不知道如何很好地失败


    更好的解决方案可能使用python的AST,但我不知道如何访问它

    您可以使用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("")
    
    结果:

    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
    

    您应该编写一个解析器。正则表达式的功能还不够强大,这太棒了。我从来都不知道你能做到!
    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