Python2和Python3有很大的不同,six这个库为此提供了一个兼容的方案。使用six写的代码可以不用修改就运行在Python2或Python3上。注意这个six并不是让Python2写的代码兼容Python3,如果你需要迁移工具,那么你要找的是2to3。如果你的代码需要同时需要运行在Python2和Python3上,那么你就需要six!
原理其实很简单,six对Python2和Python3的名字等做了统一,比如Python2的字符串叫str
,Python3叫unicode
,那么就可以使用six.text_type
。如果运行在Python2上,six.text_type
就是unicode
,如果运行在Python3上,six.text_type
就是str
。
six库只有一个文件:six.py。这样做可以方便地拷贝到你的项目中。也可以使用pip安装。
1 |
pip install six |
(为什么叫six? 因为2 * 3 = 6。为什么不是+,因为*更牛逼)
下面讲一下six有哪些功能。
统一了Python2和Python3的类型
如上文提到的,使用six中的类型,能同时在Python2和Python3中正确运行,就不用自己在写代码的时候自己判断到底是Python2的unicode还是Python3的str了!
Python2:
1 2 3 4 5 6 |
>>> import six >>> s = u"hello" >>> type(s) <type 'unicode'> >>> isinstance(s, six.string_types) True |
Python3
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Python 3.6.1 (default, Apr 4 2017, 09:40:21) Type 'copyright', 'credits' or 'license' for more information IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help. In [1]: import six In [2]: s = "hello" In [3]: type(s) Out[3]: str In [4]: isinstance(s, six.string_types) Out[4]: True |
(由于iPython不再支持Python2,所以博主用的REPL for python2是默认的,但是在这里不影响结果)
内部对象属性的重命名
Python3修改了一些解释器内部属性的名字,例如Python2的dictionary.iterlists()
在Python3中变成了dictionary.lists()
,(讲真我觉得Python3的名字改得好!)。
使用six可以同时兼容这两种名字,但是需要将调用的格式改为 six.iterlists(dictionary, **kwargs)
。
全部的名字兼容可以参考文档。(话说我不太明白为什么保留的是Python2的名字,不用Python3的)
移动模块的位置
Python3重新组织了很多模块的位置,例如Python2的HTMLParser,在Python3中是html.parser。
我们可以使用six导入:
1 |
from six.moves import html_parser |
其他
其他的内容可以在官方的文档找到,基本上就是通过six来调用,而不是自己对Python判断。包括:
- 提供了二进制和文本数据的兼容
- uniittest assert的兼容
- urllib库改动的兼容
- 高级的自定义move
Pingback: firewalld修复 ModuleNotFoundError: No module named ‘six’ – 筱枫的小小空间