|
|
|
|
移动端

1.5.3 用于保持跨版本兼容性的常用工具和技术

《Python高级编程(第2版)》第1章Python现状,本章将会向读者介绍一下Python 3的当前现状,同时介绍Python的现代开发方法。本节为大家介绍用于保持跨版本兼容性的常用工具和技术。

作者:张亮/阿信 译来源:人民邮电出版社|2018-01-29 17:48

技术沙龙 | 邀您于8月25日与国美/AWS/转转三位专家共同探讨小程序电商实战

1.5.3 用于保持跨版本兼容性的常用工具和技术

在Python不同版本之间保持兼容性是一项挑战。根据项目的大小不同,这项挑战可能会增加许多额外的工作量,但绝对可行,也很值得去做。对于在许多环境中都会用到的Python包来说,必须要保持跨版本兼容性。如果开源包没有定义明确并经过测试的兼容范围(compatibility bound),是不太可能流行起来的。而且,对于只在公司网络封闭使用的第三方代码来说,也可以大大受益于在不同环境中的测试。

这里应该注意,虽然这一部分内容主要关注Python不同版本之间的兼容,但这些方法也适用于保持与外部依赖项之间的兼容,外部依赖项包括不同的包版本、二进制库、系统或外部服务等。

整个过程主要分为3个部分,按重要性排序如下。

定义并记录目标兼容范围的及其管理方法。

在每个环境中进行测试,并对每个兼容的依赖版本进行测试。

实现实际的兼容代码。

告知兼容范围是整个过程中最重要的一部分,因为这可以让代码使用者(开发人员)对代码的工作原理和未来的变化方式有一定的预期和假设。我们的代码可能用于多个不同项目的依赖,这些项目也在努力管理兼容性,所以把代码兼容性说清楚还是很重要的。

本书总是尽量给出几个选择,而不会强烈推荐某个特定选项,而这里是少数几个例外之一。目前来看,管理兼容性未来变化的最佳方法,就是正确使用语义化版本(Semantic Versioning semver)的版本号。它是一个广为接受的标准,用仅包含3个数字的版本标识符来标记代码的变化范围。它还给出了如何处理弃用的方法建议。下面是摘录semver官网的摘要。

版本格式:主版本号.次版本号.修订号,版本号递增规则如下。

主版本号(MAJOR):当你做了不兼容的API修改。

次版本号(MINOR):当你做了向后兼容的功能性新增。

修订号(PATCH):当你做了向后兼容的问题修正。

先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。

测试时就会发现一个悲伤的事实,为了保证代码与每个依赖版本和每个环境(这里环境指的是Python版本)都保持兼容,必须在所有可能的组合中对代码进行测试。当然,如果项目的依赖很多,做到这一点基本是不可能的,因为随着依赖版本数目的增加,组合的数目也会迅速增加。因此,通常需要做一些权衡,使得运行所有兼容性测试无需花费数年的时间。第10章中介绍一般的测试,里面也介绍了所谓的矩阵测试中工具的选择。

项目遵循semver的好处在于,通常只有主版本才需要测试,因为次版本和修订版本中保证没有向后不兼容的变化。只有项目不违背这样的约定,这种说法才能成立。不幸的是,每个人都会犯错,许多项目中都出现了后向不兼容的变化,甚至在修订版本中也出现了这种变化。尽管如此,由于semver声称对次版本和修订版本的变化保持严格的向后兼容,那么打破这个规则就可以视为bug,可以在修订版本中进行修复。

如果明确定义了兼容范围并严格测试,那么实现兼容层就是最后一步,也是最不重要的一步。但是,每一位对这个话题感兴趣的程序员都应该知道下列工具和技术。

最基本的就是Python的__future__模块。它将Python新版本中的一些功能反向迁移到旧版本中,采用的是导入语句的形式:

  1. from __future__ import <feature> 

future语句提供的功能是和语法相关的元素,其他方法很难处理这些元素。这个语句只能影响它所在的模块。下面是Python 2.7交互式会话的实例,从Python 3.0中引入Unicode:

  1. Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit  
  2. (Intel)] on win32  
  3. Type "help", "copyright", "credits" or "license" for more  
  4. information.  
  5. >>> type("foo")  # 旧的字面值  
  6. <type 'str'> 
  7. >>> from __future__ import unicode_literals  
  8. >>> type("foo")  # 现在变成了unicode  
  9. <type 'unicode'> 

下面列出了所有可用的__future__语句,关注2/3兼容性的开发者都应该知道。

division:Python 3新增的除法运算符(PEP 238)。

absolute_import:将所有不以点字符开头的import语句格式解释为绝对导入(PEP 328)。

print_function:将print语句变为函数调用,所以在print后面必须加括号(PEP 3112)。

unicode_literals:将每个字符串解释为Unicode(PEP 3112)。
__future__中的可选语句列表很短,只包含几个语法功能。对于其他变化的内容,例如元类语法(第3章会讲到这一高级特性),维持其兼容性则困难得多。future语句也无法完全解决多个标准库重组的问题。幸运的是,有些工具旨在提供一致可用的兼容层。最有名的就是Six模块,提供了常用的2/3兼容性的整个样板。另一个很有前途但名气稍逊的工具是future模块。

在某些情况下,开发人员可能不想在一些小型Python包里添加其他依赖项。通常的做法是将所有兼容性代码放在一个附加模块中,该模块通常命名为compat.py。下面是来自python-gmaps项目的compat模块实例:

  1. # -*- coding: utf-8 -*-  
  2.    import sys  
  3.  
  4.    if sys.version_info < (3, 0, 0):  
  5.        import urlparse  # noqa  
  6.  
  7.        def is_string(s):  
  8.            return isinstance(s, basestring)  
  9.  
  10.    else:  
  11.        from urllib import parse as urlparse  # noqa  
  12.  
  13.        def is_string(s):  
  14.            return isinstance(s, str) 

这样的compat.py模块十分常见,即使是利用Six保持2/3兼容性的项目也很常见,因为这种方法非常方便,用于保存在不同版本的依赖包之间保持兼容性的代码。

下载示例代码

你可以用自己的账号在Packt的官方网站下载本书的示例代码文件。如果你是在其他地方购买的本书,你可以访问Packt的官方网站并注册,文件会直接通过邮件发送给你。

下载代码文件的步骤如下。

用你的电子邮件地址和密码登录或注册我们的网站。

将鼠标指针悬停在顶部的SUPPORT选项卡上。

单击Code Downloads & Errata。

在Search框中输入本书的名字。

选择你要下载代码文件的书籍。

从下拉菜单中选择本书的购买途径。

单击Code Download。

文件下载完成后,请确保用下列软件的最新版本对文件夹进行解压或提取。

在Windows上用WinRAR或7-Zip。

在Mac上用Zipeg、iZip或UnRarX。

在Linux上用7-Zip或PeaZip。

本书的代码包也托管在GitHub,网址为https://github.com/ PacktPublishing/Expert-Python-Programming_Second- Edition。在GitHub上还有大量图书和视频资源。去看一下吧!

喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:365934973

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

Linux指令速查手册

Linux是一款开源的操作系统,得到了广大开发者的青睐。掌握Linux系统的指令及其用法是学习Linux系统的基础。本书详细地介绍了常用Linux指令...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊