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 <module>
    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 "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 665, in exec_module
  File "<frozen importlib._bootstrap>", 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 <module>
    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('<I', buf[:4])[0]
struct.error: unpack requires a bytes object of length 4

该 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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容