python 抽象语法树中的赋值运算符重载

Assignment operator overloading in python Abstract Syntax Trees

我想使用 Abstract Syntax Trees

动态重载 python 中的赋值运算符
import ast
import astunparse

class OverloadAssignments(ast.NodeTransformer):
    def visit_Assign(self, node):
        if isinstance(node, ast.Assign) and node.targets:
            funcs = node.targets[0]
            slot_name_candidate = astunparse.unparse(funcs).strip()
            if isinstance(funcs, ast.Name) and "_slot" in slot_name_candidate:
                slot_name = ast.Constant(value=slot_name_candidate)
                context_variable = ast.Constant(value=astunparse.unparse(node.value).strip())
                return ast.Expr([ast.Call(func=ast.Name(id='copy_variable_value', ctx=ast.Load),
                                          args=[slot_name, context_variable], keywords=[])])
            else:
                return node
        return node

assignment_overloader = OverloadAssignments()
code_chunk = "town_slot=cxt.my_town"
tree = ast.parse(code_chunk)
tree = assignment_overloader.visit(tree)

我使用 parseprint 函数从这里漂亮地打印代码树结构 https://bitbucket.org/takluyver/greentreesnakes/src/master/astpp.py

http://alexleone.blogspot.co.uk/2010/01/python-ast-pretty-printer.html

这给了我结果

parseprint(tree)

Module(body=[
    Expr(value=[
        Call(func=Name(id='copy_variable_value', ctx=<class 'ast.Load'>), args=[
            Constant(value='town_slot', kind=None),
            Constant(value='cxt.my_town', kind=None),
          ], keywords=[]),
      ]),
  ], type_ignores=[])

我需要将代码解析为字符串。我用另一个 python 包来做:

astunparse.unparse(tree)

AttributeError: 'Unparser' object has no attribute '_str'

失败了。

在这种情况下导致 astunparse 失败的原因是什么?

如何正确解析上述代码?

我希望 astunparse 生成以下代码块:

copy_variable_value("town_slot", "cxt.my_town")

您不需要使用 astunparseast 模块包含一个 unparse 方法:

import ast
class AssignOverload(ast.NodeTransformer):
   def visit_Assign(self, node):
      return ast.Call(func=ast.Name(id='copy_variable_value'), 
         args=[ast.Constant(value=ast.unparse(i)) for i in [*node.targets, node.value]], 
         keywords=[])

code_chunk = "town_slot=cxt.my_town"
a = AssignOverload()
result = a.visit(ast.parse(code_chunk))
print(ast.unparse(result))

输出:

copy_variable_value('town_slot', 'cxt.my_town')