zoukankan      html  css  js  c++  java
  • 管理 Python 多版本,pyenv 用起来

    介绍

    学习使用pyenv在本地安装多个 Python 版本,这样既不影响工作,也不影响生活~

    pyenv 可让你轻松地在多个 Python 版本之间切换。它简单、不引人注目,并且遵循 UNIX 的单一职责的传统,可以很好地完成一件事。

    安装 pyenv

    1. 在 mac 上,使用brew
    $ brew install pyenv
    
    1. 在 shell 中配置 pyenv 的初始化
    $ echo 'eval "$(pyenv init --path)"' >> ~/.zprofile
    

    更多安装方式见官网安装文档

    pyenv 常用命令

    查看所有可安装的 Python 版本

    $ pyenv install -list
    Available versions:
      2.1.3
      2.2.3
      2.3.7
      2.4.0
      2.4.1
      2.4.2
      ...
      3.9.1
      3.9.2
      3.9.3
      3.9.4
      3.9.5
      3.10.0b2
      3.10-dev
      3.11-dev
    

    查看已安装的 Python 版本

    $ pyenv versions
      system
    * 3.7.10 (set by /Users/zioyi/.pyenv/version)
    

    安装指定 Python 版本

    $ pyenv install 3.10.0b2
    Downloading 3.10.0b2...
    -> https://downloads.python.org/3.10.0b2.tar.bz2
    Installing 3.10.0b2...
    Installed 3.10.0b2 to /Users/zioyi/.pyenv/versions/3.10.0b2
    

    全局环境指定 Python 版本

    $ pyenv global 3.10.0b2
    $ python
    Python 3.10.0b2 (default, Jul 29 2021, 09:57:10) [Clang 12.0.5 (clang-1205.0.22.9)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 
    

    当前 shell 下指定 Python 版本

    $ pyenv local 3.7.10
    $ python
    Python 3.7.10 (default, Jul 29 2021, 09:57:10) [Clang 12.0.5 (clang-1205.0.22.9)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 
    

    备注:local 的优先级高于 global,后面的原理以后讲到

    卸载已安装的 Python 版本

    $ pyenv uninstall pypy3.7-7.3.5
    pyenv: remove /Users/zioyi/.pyenv/versions/pypy3.7-7.3.5? [y|N]y
    pyenv: pypy3.7-7.3.5 uninstalled
    

    更多用法见官网命令手册

    pyenv 的原理

    实际上, pyenv 的秘密就藏在安装 pyenv部分的第二步:初始化 pyenv

    eval "$(pyenv init -)"
    

    因为这行命令写在.zprofile文件中,所以在每次登录 shell ,都会去执行,它的效果是在PATH中加入 pyenv 相关的路径

    $ echo $PATH
    ***:/Users/zioyi/.pyenv/shims:/Users/zioyi/.pyenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:***
    

    Linux 执行命令时,是依次遍历 PATH 环境变量的每个路径,查找所执行的命令。当在某个目录下找到第一个匹配时即停止遍历,所以 PATH 环境变量中,前面的路径比后面的路径具有更高的优先级。

    系统默认的 Python 一般是在/usr/bin目录下面,而 pyenv 的路径/Users/zioyi/.pyenv/shims在其之前,所有当我们在 shell 中去执行 Python 命令时,会现在 pyenv 的目录里去找

    $ which python
    /Users/zioyi/.pyenv/shims/python
    

    我们将 shim 称作垫片,它就像是 shell 和 Python 之间的一层代理,pyenv 在 ~/.pyenv/shims 目录下创建了各种 Python 版本相关命令的垫片

    $ ls ~/.pyenv/shims
    2to3                     flask                    jupyter-bundlerextension jupyter-troubleshoot     pycodestyle              pytest-bdd               python3.7-gdb.py         rst2odt_prepstyles.py
    2to3-3.10                idle                     jupyter-console          jupyter-trust            pydoc                    pytest-benchmark         python3.7m               rst2pseudoxml.py
    2to3-3.7                 idle3                    jupyter-kernel           libpypy3-c.dylib         pydoc3                   python                   python3.7m-config        rst2s5.py
    __pycache__              idle3.10                 jupyter-kernelspec       mako-render              pydoc3.10                python-config            pyvenv                   rst2xetex.py
    coverage                 idle3.7                  jupyter-migrate          pep8                     pydoc3.7                 python3                  pyvenv-3.7               rst2xml.py
    coverage-3.7             iptest                   jupyter-nbconvert        pip                      pyflakes                 python3-config           rst2html.py              rstpep2html.py
    coverage3                iptest3                  jupyter-nbextension      pip3                     pygmentize               python3.10               rst2html4.py             send2trash
    cpuinfo                  ipython                  jupyter-notebook         pip3.10                  pypy                     python3.10-config        rst2html5.py
    easy_install             ipython3                 jupyter-qtconsole        pip3.7                   pypy3                    python3.10-gdb.py        rst2latex.py
    easy_install-3.7         jsonschema               jupyter-run              py.test                  pypy3.7                  python3.7                rst2man.py
    flake8                   jupyter                  jupyter-serverextension  py.test-benchmark        pytest                   python3.7-config         rst2odt.py
    
    

    所以当我们执行 python 相关的命令时,实际执行的是这些垫片。这些垫片的内容都是相同的:

    $ cat ~/.pyenv/shims/python
    #!/usr/bin/env bash
    set -e
    [ -n "$PYENV_DEBUG" ] && set -x
    
    program="${0##*/}"
    
    export PYENV_ROOT="/Users/zioyi/.pyenv"
    exec "/usr/local/opt/pyenv/bin/pyenv" exec "$program" "$@"
    

    从脚本内容可以看出,当我们执行某个命令 program "param1" "param2" ……时,实际执行的是 pyenv exec "program" "param1" "param2" ……。
    例如执行python -V,实际执行的是pyenv exec python -V

    pyenv exec命令中,首先会调用pyenv version name确定 python 版本或虚拟环境版本,具体查找规则为:

    pyenv exec命令中,会再调用pyenv which确定可执行文件 program 的路径。如果前面pyenv version name确定了 Python 版本或虚拟环境版本,则使用<pyenv 安装路径>/versions/<版本号>/bin/<程序名><pyenv 安装路径>/versions/<版本号>/env/<虚拟环境名>/bin/<程序名>,否则遍历所有版本号的安装路径,按顺序取第一个匹配到的可执行文件。

    确定与版本号对应的可执行文件路径 path 之后,执行以下命令:

    exec -a program "$path" "param1" "param2" 
    # 注:即执行 "path" "param1" "param2",并使用 program 作为程序名,程序名即 shell 中的 $0,python 中的 sys.argv0
    

    例如执行python -V,确定 pyenv 版本为 3.10.0b2,对应可执行文件为~/.pyenv/versions/3.10.0b2/bin/python,则执行命令为:

    exec -a python ~/.pyenv/versions/3.10.0b2/bin/python -V
    

    以上就是 pyenv 执行命令的基本原理了

    总结

    pyenv 可以很好的帮助我们管理 Python 的多版本问题。当不同的工程项目所需的 Python 版本不同时,可以通过 pyenv 来方便管理;当我们想尝鲜 Python3.10 而又担心污染开发环境时,也可以使用 pyenv。

  • 相关阅读:
    洛谷—— P2234 [HNOI2002]营业额统计
    BZOJ——3555: [Ctsc2014]企鹅QQ
    CodeVs——T 4919 线段树练习4
    python(35)- 异常处理
    August 29th 2016 Week 36th Monday
    August 28th 2016 Week 36th Sunday
    August 27th 2016 Week 35th Saturday
    August 26th 2016 Week 35th Friday
    August 25th 2016 Week 35th Thursday
    August 24th 2016 Week 35th Wednesday
  • 原文地址:https://www.cnblogs.com/Zioyi/p/15079567.html
Copyright © 2011-2022 走看看