Mac下Python2升级到Python3之后yd包不兼容问题踩坑历程

最近用Mac brew安装一些包的时候顺带把Python从2.7升级到了3.7,导致之前在Python2下安装的很多包用不了了,例如yd、ipython、musicbox等:

1
2
3
╭─zuolicong@zuolicongdeAir ~
╰─$ musicbox
zsh: /usr/local/bin/musicbox: bad interpreter: /usr/local/opt/python/bin/python2.7: no such file or directory

平时用yd命令翻译单词还是挺方便的,于是就想着索性用pip3再安装一遍,反正Python2后面也要被淘汰了。然而以为很简单的事,却一顿折腾。运行pip3 install yd先报了这么一个错:

1
ModuleNotFoundError: No module named 'version'

踩坑历程

既然没有version包,那就再安装一个呗,于是pip3 install version,然而又报这个:

1
importError: cannot import name 'izip_longest'

在网上查了下,itertools.izip在pyhton3中已被去掉了,zip成为内置的方法。解决方法是找到version包源文件中使用了”from itertools import izip_longest”的文件, 将izip_longest改为zip_longest,再手动安装,然而/usr/local/lib/python3.7/site-packages目录下也没有pip3下载的version包源文件,我试着用pip3 download version,仍然报上面那个错。看来只能去官网下载了:https://pypi.org/project/version/

官网的version包链接到了https://github.com/keleshev/version ,可以直接下载zip文件,然后执行以下命令就可以安装version了:

1
2
3
4
5
6
7
8
9
10
╭─zuolicong@zuolicongdeAir ~/python-code
╰─$ pip3 install ./version-master.zip
Processing ./version-master.zip
Building wheels for collected packages: version
Building wheel for version (setup.py) ... done
Created wheel for version: filename=version-0.1.2-py3-none-any.whl size=3249 sha256=d7f32866382d5d711c6e72e0a877ac2062fc7f25bed901567cbabd9168b17abc
Stored in directory: /Users/zuolicong/Library/Caches/pip/wheels/25/58/94/317ecc66e2db4df75bb89ea3bf33401b3de1360fdb984f0428
Successfully built version
Installing collected packages: version
Successfully installed version-0.1.2

可以发现官网上的version包其实对Python2和Python3做了兼容:

1
2
3
4
if sys.version_info >= (3, 0):
from itertools import zip_longest as izip_longest
else:
from itertools import izip_longest

再运行pip3 install yd命令,bingo,安装成功,然而我还是太年轻,使用yd的时候又遇到一系列兼容问题:

1
2
3
4
5
6
7
Traceback (most recent call last):
File "/usr/local/bin/yd", line 5, in <module>
from yd.yd import main
File "/usr/local/lib/python3.7/site-packages/yd/yd.py", line 131
print output
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(output)?

Python2中的”print output”在Python3中需要改成”print(output)”

1
2
3
4
5
6
Traceback (most recent call last):
File "/usr/local/bin/yd", line 5, in <module>
from yd.yd import main
File "/usr/local/lib/python3.7/site-packages/yd/yd.py", line 4, in <module>
import environ
ModuleNotFoundError: No module named 'environ'

继续pip3 install environ

1
2
3
4
5
6
7
8
9
Traceback (most recent call last):
File "/usr/local/bin/yd", line 5, in <module>
from yd.yd import main
File "/usr/local/lib/python3.7/site-packages/yd/yd.py", line 4, in <module>
import environ
File "/usr/local/lib/python3.7/site-packages/environ.py", line 114
raise ValueError, "No frame marked with %s." % fname
^
SyntaxError: invalid syntax

Python3中raise用法需要改成:raise ValueError(“No frame marked with %s.” % fname)

1
2
3
4
5
6
7
8
9
10
Traceback (most recent call last):
File "/usr/local/bin/yd", line 5, in <module>
from yd.yd import main
File "/usr/local/lib/python3.7/site-packages/yd/yd.py", line 4, in <module>
import environ
File "/usr/local/lib/python3.7/site-packages/environ.py", line 250, in <module>
ctx = Environ(None)
File "/usr/local/lib/python3.7/site-packages/environ.py", line 105, in __init__
elif isinstance(frame, basestring):
NameError: name 'basestring' is not defined

Python3中”basestring”需要改成”str”

然而无解的来了:

1
2
3
4
5
6
Traceback (most recent call last):
File "/usr/local/bin/yd", line 5, in <module>
from yd.yd import main
File "/usr/local/lib/python3.7/site-packages/yd/yd.py", line 7, in <module>
import ydsearch
ModuleNotFoundError: No module named 'ydsearch'

执行pip3 install ydsearch报:

1
2
ERROR: Could not find a version that satisfies the requirement ydsearch (from versions: none)
ERROR: No matching distribution found for ydsearch

这么说来Python3压根就不支持yd包,害我还折腾了这么长时间。于是想到go是不是有类似的包可以替代,于是github上搜了下发现了这个:https://github.com/TimothyYe/ydict ,于是

1
go get -v github.com/TimothyYe/ydict

嗯,真香。

一点想法

只能说Python 2和3兼容性真的太差,如果项目想从2升级到3成本太高,导致生态有点割裂。感觉设计者初期没太想好。不过我等屁民也不好评判大佬当初的想法,只能尽量避免踩坑,或者寻求可替代的方案,比如go。当然不同的语言使用的场景不同,适合的才是最好的。