我有一些为 Python 3.5 编写的源代码,我想使其在 Python 3.4 下可执行。我使用的 3.5 中唯一在 3.4 中不可用的功能是类型提示,因此我想编写一个脚本来完全删除这些功能。
乍一看这似乎很容易,我决定编写一些正则表达式这样做,但后来我想到了一些边缘情况,我不确定如何解决像这样的更复杂函数的问题:
def foo(bar: Dict[T, List[T]],
baz: Callable[[T], int] = lambda x: (x+3)/7,
**kwargs) -> List[T]:
基本上,我必须解析整个事情并重建参数列表没有类型注释。我该如何处理这个问题呢?
不要试图自己写这个。Python 代码解析很复杂。使用 ast 模块是更好的选择,它允许以更结构化的方式操作 Python 代码。
以下脚本将完成此任务:
import ast
def remove_type_hints(source):
"""从 Python 源代码中删除类型提示。
Args:
source: 要从中删除类型提示的 Python 源代码。
Returns:
不带类型提示的 Python 源代码。
"""
tree = ast.parse(source)
class RemoveTypeHints(ast.NodeTransformer):
def visit_FunctionDef(self, node):
node.args.args = [arg for arg in node.args.args if not arg.annotation]
node.args.kwonlyargs = [arg for arg in node.args.kwonlyargs if not arg.annotation]
node.returns = None
return node
def visit_AnnAssign(self, node):
return None if node.simple else ast.Assign([node.target], node.value)
return ast.unparse(RemoveTypeHints().visit(tree))
source = """
def foo(bar: Dict[T, List[T]],
baz: Callable[[T], int] = lambda x: (x+3)/7,
**kwargs) -> List[T]:
pass
x: int = 1
"""
print(remove_type_hints(source))
这将输出以下内容,它删除了所有类型提示,同时保留了其他代码:
def foo(bar, baz=lambda x: (x + 3) / 7, **kwargs):
pass
x = 1
此脚本使用
ast
模块解析 Python 代码并找到所有函数定义和变量声明。然后,它删除类型提示并使用修改后的 AST 生成新的 Python 代码。此方法比使用正则表达式更可靠、更易于维护。