Python AST:TypeError 重写节点
Python AST : TypeError Rewriting Node
我正在尝试使用 PLY 和 Python 的 AST 从头开始创建方程求解器。
从输入2 + x
开始我先翻译成N.Number(2) + x
。为什么?因为我使用自己的 Class 作为实数。
现在,我正在根据第一步的输出创建一个 AST。在这里,我想重写 'x',通过函数调用节点更改其名称节点以获得如下内容:N.Number(2) + N.Number(42)
.
但是我得到了这个类型错误:
Traceback (most recent call last):
File "test_ast.py", line 52, in <module>
print(eval(compile(yop, filename="", mode="eval")))
TypeError: required field "value" missing from Attribute
到目前为止,这是我的代码:
class RewriteName(ast.NodeTransformer):
def visit_Name(self, node):
if node.id == 'x':
return ast.copy_location(ast.Call(func=ast.Attribute(value=ast.Name(id='N', ctx=ast.Load()), attr='Number', ctx=ast.Load()),
args=[ast.Num(n=42)],
keywords=[]
), node)
question = "N.Number(2) + x"
yop = ast.parse(question, mode="eval")
print(ast.dump(yop))
RewriteName().visit(yop)
print(ast.dump(yop))
print(eval(compile(yop, filename="", mode="eval")))
问题显然来自 Rewrite_Name class。注意它周围的两个印刷品:这些是它们的输出:
Expression(body=BinOp(left=Call(func=Attribute(value=Name(id='N', ctx=Load()), attr='Number', ctx=Load()), args=[Num(n=2)], keywords=[]), op=Add(), right=Name(id='x', ctx=Load())))
Expression(body=BinOp(left=Call(func=Attribute(attr='Number', ctx=Load()), args=[Num(n=2)], keywords=[]), op=Add(), right=Call(func=Attribute(value=Name(id='N', ctx=Load()), attr='Number', ctx=Load()), args=[Num(n=42)], keywords=[])))
我对 Rewrite_Name class 的调用错误地更改了表达式 BinOp 左侧的某些内容,但我不知道为什么。
有人可以帮助我吗?
我认为您收到此错误是因为当您访问第一个 Name 时,它的 ID 不是 x。在此代码中,您的函数 visit_Name
returns None
.
添加一个else: return node
class RewriteName(ast.NodeTransformer):
def visit_Name(self, node):
if node.id == 'x':
return ast.copy_location(ast.Call(func=ast.Attribute(value=ast.Name(id='N', ctx=ast.Load()), attr='Number', ctx=ast.Load()),
args=[ast.Num(n=42)],
keywords=[]
), node)
else:
return node
将帮助您避免 required field "value" missing from Attribute
...
只是为了得到另一个 TypeError: required field "lineno" missing from expr
;-)
我正在尝试使用 PLY 和 Python 的 AST 从头开始创建方程求解器。
从输入2 + x
开始我先翻译成N.Number(2) + x
。为什么?因为我使用自己的 Class 作为实数。
现在,我正在根据第一步的输出创建一个 AST。在这里,我想重写 'x',通过函数调用节点更改其名称节点以获得如下内容:N.Number(2) + N.Number(42)
.
但是我得到了这个类型错误:
Traceback (most recent call last):
File "test_ast.py", line 52, in <module>
print(eval(compile(yop, filename="", mode="eval")))
TypeError: required field "value" missing from Attribute
到目前为止,这是我的代码:
class RewriteName(ast.NodeTransformer):
def visit_Name(self, node):
if node.id == 'x':
return ast.copy_location(ast.Call(func=ast.Attribute(value=ast.Name(id='N', ctx=ast.Load()), attr='Number', ctx=ast.Load()),
args=[ast.Num(n=42)],
keywords=[]
), node)
question = "N.Number(2) + x"
yop = ast.parse(question, mode="eval")
print(ast.dump(yop))
RewriteName().visit(yop)
print(ast.dump(yop))
print(eval(compile(yop, filename="", mode="eval")))
问题显然来自 Rewrite_Name class。注意它周围的两个印刷品:这些是它们的输出:
Expression(body=BinOp(left=Call(func=Attribute(value=Name(id='N', ctx=Load()), attr='Number', ctx=Load()), args=[Num(n=2)], keywords=[]), op=Add(), right=Name(id='x', ctx=Load())))
Expression(body=BinOp(left=Call(func=Attribute(attr='Number', ctx=Load()), args=[Num(n=2)], keywords=[]), op=Add(), right=Call(func=Attribute(value=Name(id='N', ctx=Load()), attr='Number', ctx=Load()), args=[Num(n=42)], keywords=[])))
我对 Rewrite_Name class 的调用错误地更改了表达式 BinOp 左侧的某些内容,但我不知道为什么。
有人可以帮助我吗?
我认为您收到此错误是因为当您访问第一个 Name 时,它的 ID 不是 x。在此代码中,您的函数 visit_Name
returns None
.
添加一个else: return node
class RewriteName(ast.NodeTransformer):
def visit_Name(self, node):
if node.id == 'x':
return ast.copy_location(ast.Call(func=ast.Attribute(value=ast.Name(id='N', ctx=ast.Load()), attr='Number', ctx=ast.Load()),
args=[ast.Num(n=42)],
keywords=[]
), node)
else:
return node
将帮助您避免 required field "value" missing from Attribute
...
只是为了得到另一个 TypeError: required field "lineno" missing from expr
;-)