如果Python外部库支持Python3独占特性,它如何在向后兼容Python2时不引起解释器问题?

如果Python外部库支持Python3独占特性,它如何在向后兼容Python2时不引起解释器问题?,python,python-3.x,backwards-compatibility,Python,Python 3.x,Backwards Compatibility,关于外部库的一些问题,以及旧版Python解释器如何处理利用旧版解释器没有的功能的外部库,以及打包一个可能向后兼容的库 我第一次在matmul操作符和numpy中遇到这个问题-matmul(@)操作符是3.5的一个特性,当我创建这个简单的示例时 import numpy as np array1 = np.array([[1, 2],[3, 4]]) array2 = np.array([3, 4]) array3 = array1 @ array2 如果我在python2.7.16中运行

关于外部库的一些问题,以及旧版Python解释器如何处理利用旧版解释器没有的功能的外部库,以及打包一个可能向后兼容的库

我第一次在matmul操作符和numpy中遇到这个问题-matmul(@)操作符是3.5的一个特性,当我创建这个简单的示例时

import numpy as np 

array1 = np.array([[1, 2],[3, 4]])
array2 = np.array([3, 4])
array3 = array1 @ array2
如果我在python2.7.16中运行它,它会抛出一个无效的语法错误,而在Python3.7中也可以。如果在某个地方它必须具有早期Python中不存在的uuu matmul_uuuudunder,那么为什么跟踪不在numpy中呢?同样,类型提示的问题也存在:当我用类型提示更新那小块代码时,它会导致2.7的语法错误——如果有人为3.x制作了一个很好的包,里面有有用的类型提示,一个3.5功能,有人pip从鸡蛋或轮子上安装它,然后通过python2运行它,口译员是如何处理的?f字符串也一样,添加了3.5/3.6。我这样问是因为我有一个包,我想作为一个轮子分发,理想情况下它适用于2.7版本,但我到处都有类型提示和f字符串


我想我的问题的总结是:如果可以的话,你如何保证你的软件包及其所有优秀的Python3功能向后兼容旧的python?使用外部库或从wheel/egg安装的东西与导入有何不同?(特别是对于一个egg,据我所知,它仍然提供原始源代码,而wheel正在进行某种编译/“构建”(不确定“构建”在Python上下文中的含义,我的理解是您将源代码提供给解释器,它在运行时生成字节码,解释器从不“构建”)(编译)对象文件或可执行文件(如编译语言))

通常,要么是侥幸,要么是他们避免实际使用任何Python 3功能,即使他们提供了对此类功能的支持

如果在某个地方它必须具有早期Python中不存在的
\uuu matmul\uuu
dunder,那么为什么跟踪本身不在numpy中

在Python2上,仅仅命名一个方法
\uuuu matmul\uuuu
并不是语法错误。试图使用
@
运算符是一个语法错误。(不过,NumPy不再支持python2,所以要么使用旧的NumPy,要么导入时没有错误,这完全是侥幸。)

同样,类型提示的问题也存在:当我用类型提示更新那小块代码时,它会导致2.7的语法错误——如果有人为3.x制作了一个很好的包,里面有有用的类型提示,一个3.5功能,有人pip从鸡蛋或轮子上安装它,然后通过python2运行它,口译员是如何处理的

Python2上有一个“类型注释”语法,或者它们可以分发单独的类型存根文件,而不是使用内联注释。如果他们直接在
.py
文件中使用注释语法,则会导致语法错误

f字符串也一样,添加了3.5/3.6

语法错误

我这样问是因为我有一个包,我想作为一个轮子分发,理想情况下它适用于2.7版本,但我到处都有类型提示和f字符串

你有不切实际的兼容性期望。您必须使用类型注释和
str.format

如果可以的话,您如何保证您的软件包及其所有优秀的Python3功能向后兼容较旧的Pythons


通过不使用Python3特性。

此时,需要Python2.7支持的人并不是在编写新代码:他们在维护现有代码,而这些代码可能不会获得新特性。您的目标受众几乎肯定会同意放弃对Python 2的支持;大量突破性的更改使得转换比预期的更困难,导致Python2关闭的时间比预期的要长得多。