首先解决了一个 Pyenv 多版本共存的问题,之前要么用 Python2.7 要么用最新版的 Python,现在怀疑是 Python3.5 导致的问题,所以要用 Pyenv 装一个多Python的环境。
在 OS X 上面安装 Pyenv 非常简单:
1 2 |
➜ brew install pyenv ➜ echo 'export PATH="/Users/username/.pyenv:$PATH"\n eval "$(pyenv init -)"'>> ~/.zshrc |
用 Pyenv 下载一个新的Python:
1 |
➜ ~ pyenv install 3.5.2 |
无奈公司的网络实在太差,卡在 Downloading 那一步很久都下载不完,只要自己挂代理下载下来然后从本地安装:
1 2 3 |
➜ ~ export PYENV_ROOT=/usr/local/var/pyenv ➜ ~ proxychains wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tar.xz -P $PYENV_ROOT/cache/ ➜ ~ pyenv install 3.5.2 |
可以看到 Pyenv 里面已经新加了一个可执行的Python了(Pyenv挺有意思的,有兴趣的可以去看看它的原理):
1 2 3 4 5 6 7 |
➜ ~ pyenv versions system 3.5.2 * 3.5.3 (set by /usr/local/var/pyenv/version) ➜ ~ pyenv global 3.5.2 ➜ ~ pyenv version 3.5.2 (set by /usr/local/var/pyenv/version) |
这个使用 virualenv 创建 Python 的虚拟环境也可以用指定的 Python 版本:
1 2 3 4 5 6 7 8 9 10 |
➜ ~ mkvirtualenv py35 -p python Running virtualenv with interpreter /usr/local/var/pyenv/shims/python Using base prefix '/usr/local/var/pyenv/versions/3.5.3' New python executable in /Users/laixintao/.virtualenvs/py35/bin/python Installing setuptools, pip, wheel...done. virtualenvwrapper.user_scripts creating /Users/laixintao/.virtualenvs/py35/bin/predeactivate virtualenvwrapper.user_scripts creating /Users/laixintao/.virtualenvs/py35/bin/postdeactivate virtualenvwrapper.user_scripts creating /Users/laixintao/.virtualenvs/py35/bin/preactivate virtualenvwrapper.user_scripts creating /Users/laixintao/.virtualenvs/py35/bin/postactivate virtualenvwrapper.user_scripts creating /Users/laixintao/.virtualenvs/py35/bin/get_env_details |
好了,折腾这么一顿,实际上是想试一下今天遇到的一个诡异Bug, Python3.5 的 json
传进去 bytes
就挂了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Python 3.5.2 (default, May 3 2018, 17:13:06) [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.1)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import json >>> json.loads(b'{"foo":100}') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/var/pyenv/versions/3.5.2/lib/python3.5/json/__init__.py", line 312, in loads s.__class__.__name__)) TypeError: the JSON object must be str, not 'bytes' >>> exit() ➜ ~ python3 Python 3.6.5 (default, Mar 30 2018, 06:41:53) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import json >>> json.loads(b'{"foo":100}') {'foo': 100} |
好吧,看来 Python3.6 之前确实不支持对 bytes
直接 load()
。
PS: 今天发现 Python 官方网站有了交互式的 shell (也许很久就有了),是接入的 www.pythonanywhere.com 支持各种版本的 Python,很好用:
或者用 MacPorts,多版本并存已经通过拆包实现了,不用再装 pyenv。唯一的“缺点”是不能装更旧的 patch 版本,但相对应地也支持了在同 minor 版本内升级到最新。
virtualenv 可以跨 python 来管理吗?比如 pyenv-virtualenv 可以通过 pyenv activate myproject 命令来激活这个 venv,而不用关心这个 venv 在哪一个 Python 版本下面。如果可以的话就完美了。
venv 创建的时候可以用指定的 python 版本,MacPorts 的二进制都是带后缀的,例如这个就固定在 3.12.x 版本。
$ python3.12 -m venv v
$ ls -l v/bin/python*
v/bin/python -> python3.12
v/bin/python3 -> python3.12
v/bin/python3.12 -> /opt/local/Library/Frameworks/Python.framework/Versions/3.12/bin/python3.12
这样 activate 之后 Python 就是创建时指定的版本。