如何判断python的一行代码在语法上是否有效?

如何判断python的一行代码在语法上是否有效?,python,validation,Python,Validation,与此非常相似: 唯一的区别是,我对一行代码感兴趣,而不是给出整个程序 形式上,如果存在任何使用该特定行的语法有效的python程序,我们就说python行是“语法有效的” 例如,我想将这些行标识为语法上有效的行: for i in range(10): x = 1 for j in range(10 in range(10( x =++-+ 1+- 因为可以在一些语法有效的python程序中使用这些行 我想将这些行标识为语法无效的行: for i in range(10): x =

与此非常相似:

唯一的区别是,我对一行代码感兴趣,而不是给出整个程序

形式上,如果存在任何使用该特定行的语法有效的python程序,我们就说python行是“语法有效的”

例如,我想将这些行标识为语法上有效的行:

for i in range(10):

x = 1
for j in range(10 in range(10(

x =++-+ 1+-
因为可以在一些语法有效的python程序中使用这些行

我想将这些行标识为语法无效的行:

for i in range(10):

x = 1
for j in range(10 in range(10(

x =++-+ 1+-
因为没有语法正确的python程序可以使用这些行


检查不需要太严格,只需要足够好地过滤掉明显虚假的语句(如上图所示)。当然,行是以字符串的形式给出的。

我只是建议,不确定是否要工作。。。但是可能是使用了
exec
的东西尝试一下,除了

code_line += "\n" + ("\t" if code_line[-1] == ":" else "") + "pass"
try:
    exec code_line
except SyntaxError:
    print "Oops! Wrong syntax..."
except:
    print "Syntax all right"
else:
    print "Syntax all right"
简单的行应该会产生一个合适的答案,这个答案用于尝试编译代码。这与模块确定是请求另一行还是立即失败并出现语法错误的逻辑相同

import codeop
def is_valid_code(line):
    try:
        codeop.compile_command(line)
    except SyntaxError:
        return False
    else:
        return True
它可以按如下方式使用:

>>> is_valid_code('for i in range(10):')
True
>>> is_valid_code('')
True
>>> is_valid_code('x = 1')
True
>>> is_valid_code('for j in range(10 in range(10(')
True
>>> is_valid_code('x = ++-+ 1+-')
False
我敢肯定,在这一点上,您是在为范围内的j(范围内的10(10(
)被认为是无效的)说“给出了什么?”这一行的问题是,
10()
在技术上是有效的,至少根据Python解释器是如此。在REPL中,您得到以下信息:

>>> 10()
Traceback (most recent call last):
  File "<pyshell#22>", line 1, in <module>
    10()
TypeError: 'int' object is not callable
第二行是
True
,因为表达式可以像这样继续:

if (x ==
    3):
    print('x is 3!')
表达式将是完整的。事实上,区分这些不同情况的方法是:如果代码对象是有效的自包含行,则返回一个代码对象;如果该行预期将继续执行完整表达式,则返回
None
,并在无效行上抛出
SyntaxError

但是,你也可以进入一个比最初陈述的更复杂的问题。例如,考虑行<代码> <代码>。如果是模块的开始,或者前面的行是“代码> { <代码>”,那么它是无效的。但是,如果上一行是“代码>(1,2,< /代码>),则是完全有效的。

这里给出的解决方案如果您只向前工作,并将前面的行作为上下文附加,这是交互式会话的模块所要做的。在不考虑周围行的情况下,创建能够始终准确识别Python文件中是否可能存在一行的内容将是非常困难的,因为Python语法以非平凡的方式与换行符进行交互。这个答案的回答是,给定的一行是否可以位于模块的开头,并继续到下一行而不会失败


最好确定识别单行的目的是什么,并以不同的方式解决这个问题,而不是针对每种情况尝试解决这个问题。

FYI,
x=+1
在语法上是有效的。它将
+1
分配给
x
。隐式行连接(这将使j在范围内
)如何(10
也可能在语法上有效)
对于范围内的j(10
也有效,如果下一行继续类似于
):
,和
如果x<3
也可以是多行表达式的一部分。几乎任何东西都可以是多行字符串的一部分。我想你需要回答的问题是,为什么你需要/想要这样做
在语法上仍然有效。赋值不再有效,除非它是三行字符串的一部分uoted字符串或一行继续注释。我想你不太明白你想做什么。我正要建议
+=“pass”
方法。您可能希望
.rstrip
行。此外,您不需要新行和缩进。执行行打开了潘多拉的盒子。让我们看看
而True:
是否在语法上有效。导入操作系统('rm-rf/')怎么样
?@JohnKugelman是的,但无论如何这都需要沙盒。如果OP随机生成程序,其中一些程序可能不会停止,有些会影响环境。@JohnKugelman你是对的……但我想不出任何方法,只要不做python解释器……有人知道执行python代码的方法吗没有真正执行它?我知道这个愚蠢的问题,但可以帮助很多这与我的labmate和我刚才讨论的类似。我将尝试这种方法,并在一小时后报告。谢谢!我同意你的逻辑。但是“for j in range(10 in range)(10)(“无效,因为它有不匹配的括号(仅语法错误)”不,因为那一行可能会继续到下一行。我会在答案中解释。听起来很合理!似乎比添加“通过”并尝试编译到AST(另一个答案)更安全.我会用this@EvanPu更重要的是要知道为什么需要这样做,并尝试解决这个问题。如果你谷歌“sk_p”,我相信你会找到我关于这个的论文!