有没有一种方法可以在Python中的向后兼容代码上使用类型暗示?

2024-04-25 16:52:23 发布

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

我正在编写一些代码,希望在添加类型暗示之前能够在Python的早期版本上运行,而不需要单独的代码库。有没有一个简单的方法来实现这一点?在

from __future__ import print_function如何允许您在python2代码中使用print()类似,是否存在from __future__ import type_hints?在

duplicate question的公认答案确实提供了一种使其在2.7中工作的方法,但它没有说明在Python3中是否也能正常工作。我将在答案的注释中询问,但我的问题是寻找与python2和python3的早期版本都兼容的东西。在


Tags: 方法答案代码fromimport版本类型type
2条回答

要以完全向后兼容的方式使用类型提示,您需要。。。在

  1. Always use the comment-based syntax:python2不支持函数注释;python3.0-3.5不支持变量注释。在
  2. 使用Python2.7和3.0-3.4时安装typing module的后端口。typing模块是在python3.5中添加到标准库中的,必须为Python的早期版本安装pip。在

另外一个复杂的问题是,自从typing模块被添加到python3.5.0中的标准库中以来,它已经用新类型更新了几次,比如ClassVar、Deque、Protocol、Text、Type等等。在

如果您想使用这些类型并且仍然支持Python3.5和3.6,那么另外安装typing_extensions模块。您可以在github repo上找到后端口类型的完整列表。在

基本上,如果您想使用上面链接的github repo中列出的任何类型,并支持python3.5.0-3.6.x,请始终从typing_extensions导入它们,而不是从typing导入。在


您可能关心或不关心的其他细节和注意事项:

  1. 关于typing_extensions

    如果您计划使用typing_extensions,那么如果您需要支持python3.5.0-3.5.2,也要小心。自从python3.5.0首次发布以来,typing模块经历了几次(通常是实质性的)内部更改。在

    typing_extension模块试图以一种正常的方式在这些不同的内部api之间架起桥梁,但是总有一些东西被忽略了。不过,python3.5和python3.6的最新次要版本要更新得多,因此不太可能出现问题。在

    (如果您只想支持python3.5和3.6的最新次要版本,那么您也可以不使用typing_extensions就可以了:python3.5.0和python3.6.0中缺少的几个类型后来添加了。但实际上很难跟踪何时添加了什么内容,所以默认使用键入扩展名可能更安全,而不用担心它。)

  2. 关于mypy:

    如果要使用mypy,请记住mypyy只能使用python3的非EOL'd版本来运行。所以,在编写本文时,Python3.4+。在

    但是,mypy本身可以用来分析python2.7+代码。

  3. 关于typeshed和Python 3.0-3.2:

    Mypy和大多数其他兼容pep484的类型检查工具都依赖于typeshed,这是标准库和流行的第三方库的类型注释集合。在

    Typeshed跟踪函数和类何时添加到标准库中。这样,您就可以要求像mypy这样的工具来确保您的代码适用于特定版本的Python,并且您不会意外地从将来导入任何内容。在

    但是,typeshed只跟踪python2.7和3.3+的这些信息。因此,如果您是专门针对Python3.0-3.2的,则需要小心。

  4. 关于unicode_文字和mypy/typeshed:

    有些人建议使用unicode_literals作为一种技术来帮助实现Python2/3兼容性。在

    但是,我认为使用unicode_文字会导致typeshed或mypy的许多问题。我忘了确切的细节,但结果是你最好不要用它(至少暂时)。在

    相反,通过使用类型系统来避免与unicode相关的问题。具体来说:

    • 当某些内容必须是unicode时,请使用typing.Text。在Python2中,此类型别名为unicode,在Python3中别名为str。在
    • 使用bytes(或者bytearray?)当某些内容必须是字节时。请记住,bytes在python2和python3之间的行为略有不同。在
    • 使用str,如果该值应该是str对于特定版本的Python意味着什么。在

    如果您需要编写一个需要处理多种字符串的函数,那么可以使用谨慎的uUnion或{a7}的se。

对重复问题的公认答案似乎对python3.x(其中x<;5)有效,至少对mypy有效。在

来自mypy docs

The example below illustrates the Python 2 function type annotation syntax. This syntax is also valid in Python 3 mode:

from typing import List

def hello(): # type: () -> None
    print 'hello'

class Example:
    def method(self, lst, opt=0, *args, **kwargs):
        # type: (List[str], int, *str, **bool) -> int
        """Docstring comes after type comment."""

但是在Python3.5之前,您需要pip install typing。在

相关问题 更多 >