Expr不是表达式本身的节点,而是表达式语句—
即仅包含表达式的语句。因为抽象语法使用三种不同的标识符,这是不完全明显
Expr,
expression和
expr,所有的意义略有不同的东西。
Statement的语法允许Expr节点作为子代,但是Expr节点的语法不允许另一个Expr节点作为子代。换句话说,
args您所指的值应该是表示内容的列表,而不是
Expr节点列表。请参阅抽象语法的文档,其中包括:
stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list) | ClassDef(identifier name, expr* bases, stmt* body, expr* decorator_list) #... | Expr(expr value)
换句话说,可能的陈述是
Expr(blah),其中
blah符合的语法
expr。这是
Expr语法中的唯一用法,因此一切
Expr都可以。一个
Expr是可能的陈述,仅此而已。语法的其他地方:
expr = BoolOp(boolop op, expr* values) | BinOp(expr left, operator op, expr right) # other stuff notably excluding Expr(...) | Call(expr func, expr* args, keyword* keywords, expr? starargs, expr? kwargs)
由于
args参数
Call必须匹配
expr*,它必须是匹配的事物的清单
expr。但是一个
Expr节点不匹配
expr;
在
expr语法相匹配的表现,而不是一个表达式语句。
请注意,如果使用的“
eval”模式
compile,它将编译一个表达式,而不是一条语句,因此该
Expr节点将不存在,并且顶级
Module节点将替换为
expression:
>>> print(dump(compile('print("blah")', '<String>', 'eval', pfcf|PyCF_ONLY_AST)))expression(body=Call(func=Name(id='print', ctx=Load()), args=[Str(s=u'blah')], keywords=[], starargs=None, kwargs=None))您会看到an的主体
expression是单个表达式(即an
expr),因此
body不是列表,而是直接设置为
Call节点。但是,当您在“
exec”模式下编译时,它必须为模块及其语句创建额外的节点,并且
Expr就是这样的节点。



