Ubuntu 中使用 pyenv 控制 Python 版本

备注:

开发环境下,如果要控制 Python 版本,建议使用更加稳定的 conda。安装以后的具体使用参照 Anaconda 的虚拟环境、包管理以及 kernel 加入 notebook。

1. 概述:

Ubuntu 自带的 Python 有时会产生奇怪的 bug,但是我们不能随便更换自带 Python,因为 Ubuntu 已经与自带 Python 深度绑定,动了自带 Python 会让系统不稳定。

解决办法是使用 Python 的版本控制工具 pyenv。pyenv 之于 Python,类似于 nvm 之于 Node.js。

2. 安装 pyenv

2.2 安装 Python 编译需要的依赖文件

sudo apt-get install -y build-essential libbz2-dev libssl-dev libreadline-dev libsqlite3-dev tk-dev

# for Numpy, Matplotlib, SciPy, etc.
sudo apt-get install -y libpng-dev libfreetype6-dev 

2.2 安装 pyenv

根据 pyenv installer 中的介绍,安装方法有两种,这里用自动安装方法(而且会附带安装 pyenv-virtualenv 插件)。

curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash

2.3 配置全局变量

把以下内容写入 ~/.bashrc。如果后面不能使用,考虑放入 ~/.profile 或者 ~/.bash_profile

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

3. 使用 pyenv

3.1 安装你需要的 Python 版本

查看可以安装的 Python 版本

python pyenv install --list

安装指定版本,假设安装 Python 3.5.3

pyenv install 3.5.3

3.2 创建 Python 环境

使用 Python 3.5.3 创建一个叫 general 的环境。

pyenv virtualenv 3.5.3 general

查看现有虚拟环境

pyenv virtualenvs

进入虚拟环境 general

pyenv activate general

退出虚拟环境

pyenv deactivate

3.3 设置为全局环境

把刚才的 general 的环境设置为全局环境。

pyenv global general

如果创建了多个环境,查看已经创建了哪些环境,可以使用命令

pyenv versions

查看当前激活的版本(version 是单数)

pyenv version

4. 参考文章

4.1 pyenv 的 github 页面

pyenv

介绍 pvenv 使用与安装

4.2 Ubuntu 官网的文章

How do I install Python 3.6 using apt-get?

重点是 Nick T 的答案,值得参考

4.3 中文的 pyenv 使用介绍

pyenv及pyenv-virtual配置

Python版本管理:pyenv和pyenv-virtualenv(MAC、Linux)、virtualenv和virtualenvwrapper(windows)

Python 多版本共存之 pyenv

使用pyenv创建多版本python环境

4.4 该文提到服务器 ~/.bashrc 中可能无法生效的问题

解决FABRIC执行远程命令时无法加载PYENV的PYTHON环境

5. Ubuntu 自带 Python 的 BUG 以及解决办法

我在使用 Ubuntu 16.04 (Xenial) 的时候,Python 3.5.2 中,如果 Django 使用了 rest_framework 的时候,一旦 makemigrations 或者 migrate 就会报错 struct.error: unpack requires a bytes object of length 4

该 bug 促使我去寻找 Python 版本控制的方法。

(profiles_api) ubuntu@ubuntu-xenial:/vagrant/src/profiles_project$ python manage.py makemigrations
Traceback (most recent call last):
  File "manage.py", line 22, in 
    execute_from_command_line(sys.argv)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/core/management/__init__.py", line 363, in execute_from_command_line
    utility.execute()
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/core/management/__init__.py", line 337, in execute
    django.setup()
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/__init__.py", line 27, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models()
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/apps/config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "", line 986, in _gcd_import
  File "", line 969, in _find_and_load
  File "", line 958, in _find_and_load_unlocked
  File "", line 673, in _load_unlocked
  File "", line 665, in exec_module
  File "", line 222, in _call_with_frames_removed
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/contrib/auth/models.py", line 103, in 
    class Group(models.Model):
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/db/models/base.py", line 162, in __new__
    new_class.add_to_class(obj_name, obj)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/db/models/base.py", line 330, in add_to_class
    value.contribute_to_class(cls, name)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/db/models/fields/related.py", line 1648, in contribute_to_class
    self.remote_field.through = create_many_to_many_intermediary_model(self, cls)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/db/models/fields/related.py", line 1104, in create_many_to_many_intermediary_model
    'verbose_name': _('%(from)s-%(to)s relationship') % {'from': from_, 'to': to},
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/utils/functional.py", line 162, in __mod__
    return six.text_type(self) % rhs
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/utils/functional.py", line 119, in __text_cast
    return func(*self.__args, **self.__kw)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/utils/translation/__init__.py", line 89, in ugettext
    return _trans.ugettext(message)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/utils/translation/trans_real.py", line 338, in gettext
    return do_translate(message, 'gettext')
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/utils/translation/trans_real.py", line 321, in do_translate
    _default = _default or translation(settings.LANGUAGE_CODE)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/utils/translation/trans_real.py", line 228, in translation
    _translations[language] = DjangoTranslation(language)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/utils/translation/trans_real.py", line 129, in __init__
    self._add_installed_apps_translations()
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/utils/translation/trans_real.py", line 177, in _add_installed_apps_translations
    translation = self._new_gnu_trans(localedir)
  File "/home/ubuntu/virtualenvs/profiles_api/lib/python3.5/site-packages/django/utils/translation/trans_real.py", line 156, in _new_gnu_trans
    fallback=use_null_fallback)
  File "/usr/lib/python3.5/gettext.py", line 441, in translation
    t = _translations.setdefault(key, class_(fp))
  File "/usr/lib/python3.5/gettext.py", line 162, in __init__
    self._parse(fp)
  File "/usr/lib/python3.5/gettext.py", line 248, in _parse
    magic = unpack('

该 bug 最主要的原因是没有升级 ubuntu 的包,运行一下命令即可

$ sudo apt-get update
$ sudo apt-get -y upgrade
$ sudo apt-get install -y python3-dev sqlite python-pip
$ sudo pip install --upgrade pip
$ sudo pip install virtualenvwrapper

以下命令写入 ~/.zshrc 中确保 virtualenvwrapper 可用。

WORKON_HOME=~/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

你可能感兴趣的:(Ubuntu 中使用 pyenv 控制 Python 版本)