我正在编写处理Python AST节点的代码,该代码应与Python 2和Python 3兼容。
但是,Python 3具有ast.Try
,Python 2具有ast.TryFinally
和ast.TryExcept
,因此我需要使用visit_
别名来处理这两种情况。
如果我使用兼容性别名(如下所示)编写节点访问者代码,则在使用Python 2时,我的预提交mypy检查将会抱怨error: Name 'ast.Try' is not defined
:
import ast
class Visitor(ast.NodeVisitor):
def visit_Try(self, node): # type: (ast.Try) -> None
...
visit_TryFinally = visit_Try # python 2 compatible
如果我改用ast.TryFinally
类型提示,则error: Name 'ast.TryFinally' is not defined
如果在Python 3中运行它,它将抱怨。我知道我可以为该节点使用更通用的类型,但这使我# type: ignore
在代码中编写了很多我不愿意做的事情。不想。
我该如何解决这个问题?
Mypy知道如何处理Python版本检查,您可以使用条件类型别名为正确的Python版本选择正确的类型:
if sys.version_info[0] >= 3:
TryNode = ast.Try
else:
TryNode = ast.TryFinally
class Visitor(ast.NodeVisitor):
def visit_Try(self, node): # type: (TryNode) -> None
# ...
visit_TryFinally = visit_Try # python 2 compatible
您可以进一步节约自己的成本运行时if sys.version_info
通过将代码中的一个测试if TYPE_CHECKING:
试验。
作为一个方面说明:如果你正在处理ast.Try
在Python 3来跟踪finally:
和except ...:
该组件try
声明,要同时处理ast.TryFinally
并ast.TryExcept
在Python 2,像Python 2.5之前,你只能用try...finally
或 try...except
在一个声明。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句