先留个算法题:给一个
的长方形,最少用多少个正方形可以填补?比如给一个
的长方形,最少可以用 3 个
,2 个
总共 5 个正方形。
然后写点实践经验,2333:无脑在项目中加一个 compat.py,文件里面内容大概类似这样
try:
from urllib.parse import urlpaser
from http.client import HTTPConnection
# ...
except ImportError:
from urlparse import urlparse
from httplib import HTTPConnection
# ...
def ensure_bytes(s):
# https://github.com/benjaminp/six/blob/master/six.py#L851
pass
def ensure_text(s):
# https://github.com/benjaminp/six/blob/master/six.py#L870
pass
2. Python 2 的 str 是 bytes,Python 3 的 str 是 unicode。
老的 Python 2 项目不要轻易在代码里面加下面这个东西,会很麻烦。这个是给 Python 3 项目迁移到 Python 2 项目用的,新项目可以考虑用。
from __future__ import unicode_literals
3. 优先使用 io.open 而不是 builtins 的 open。
Py2 builtins 的 open 函数返回的总是 str(bytes)(就算是 mode 是 r),而 io.open 在 r mode 下会返回 unicode,这和 Py3 的 builtins open 行为是一致的。
4. 尽量少写类似 if version >= 3 的代码
5. 除了 six,你还可以考虑 python-future,虽然它已经快一年没更新了,但是用着还挺爽的
(等以后想起来再来更新一下这个列表)
感觉没啥好说的,单纯说写 2&3 兼容的代码,真的非常简单。
稍微需要动下脑筋的可能是涉及到 str/unicode/bytes 的地方,如果你也觉得这东西很头疼,推荐看 Pragmatic Unicode 这个文章和视频,看完就懂了。
如果觉得太长不想看,就记住2+1件事情:Python 2 会大量的对 str/bytes/unicode 对象做隐式的 encode/decode,举个栗子
>>> '好的'.encode('utf-8') # Python 2
Traceback (most recent call last):
File "", line 1, in
UnicodeDecodeError:Python 2 中 str 是 bytes,3 中 str 是 unicode
如果遇到特别难对付的错误,请检查一下系统 locale 设置。一般来说,如果是 xxx.C 的话,会有一些问题;如果是 xx.UTF-8,就是正常的。
总的来说:和动态规划那种变态的东西不一样,写兼容代码是一个经验活 + 体力活,没有什么智力上的难度。经验活 + 体力活的劳动有个特点就是:努力就有收获,人人都能成功,2333。
----------------------- 正经一点的回答 -----------------------
如果题主只是问:如何写兼容代码的话?我觉得参考以下资料就差不多
这些资料介绍了 Python 2 和 Python 3 在哪些方面有不同,并提供了能在两个环境都能 work 的代码和解决办法。
----------------------- 分割线 -----------------------
不过,我们回头思考一个问题,为什么我们要写 2&3 兼容代码,什么样的项目/情况需要写 2&3 兼容代码?
普通应用不需要兼容 Python 2 和 3,选择一个就好了。2018 年了,基础库基本也只需要支持 Python 3,很少需要支持 Python 2。
那什么情况需要写 2&3 兼容代码?大概大概只剩一种情况 Python 2 老项目兼容 Python 3。或者企业里面的新的基础库可能需要做 3&2 兼容 :thinking_face: (先忽略这个)。
----------------------- 分割线 -----------------------
所以怎样让一个 Python 2 老项目兼容 Python 3 呢?