Python类型暗示兼容性

2024-10-03 17:18:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个处理Python AST节点的代码,它应该同时兼容python2和python3。你知道吗

但是,python3有ast.Try,其中python2有ast.TryFinallyast.TryExcept,所以我需要使用visit_别名来处理这两种情况。你知道吗

如果我使用兼容性别名编写节点访问者代码,如下面所示,那么在使用Python 2时,我的pre-commit 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,那么如果我在python3中运行它,它将改为抱怨error: Name 'ast.TryFinally' is not defined。我知道我可以为节点使用更通用的类型,但是这使得我在代码中编写了很多我不想要的# type: ignore。你知道吗

如何解决此问题?你知道吗


Tags: 代码name类型节点istypenoterror
2条回答

Mypy知道how to handle Python version checks,您可以使用条件类型别名为正确的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

通过将代码放在^{} test中,可以进一步节省if sys.version_info测试的运行时开销。你知道吗

另请注意:如果要在Python3中处理ast.Try以跟踪finally:except ...:语句的try组件,则需要在Python2中同时处理ast.TryFinallyast.TryExcept,就像在Python2.5之前一样,只能在一个语句中使用try...finallytry...except。你知道吗

我在想你可以用这个代码来写剧本

import sys
import ast

class visitor(ast.NodeVisitor):

    def visit_Try(self, node):
        ...

    if sys.version.startswith("2"):
        visit_TryFinally = visit_TryFinally
    elif sys.version.startswith("3"):
        visit_TryFinally = visit_Try

sys.version.startswith()检查Python的版本。你知道吗

相关问题 更多 >