This article is participating in Python Theme Month. See the link to the event for more details
introduce
Learn how to use PyEnv to install multiple Python versions locally without affecting work or life
Pyenv lets you easily switch between multiple Python versions. It’s simple, unobtainable, and in the TRADITION of UNIX’s single responsibility, it does one thing very well.
Install pyenv
- On MAC, brew is used
$ brew install pyenv
Copy the code
- Configure pyEnv initialization in the shell
$ echo 'eval "$(pyenv init --path)"' >> ~/.zprofile
Copy the code
For details about installation methods, see the installation documentation on the official website
Pyenv common commands
View all available Python versions
$ pyenv install -listAvailable 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-devCopy the code
Check the installed Python version
$ pyenv versionsSystem * 3.7.10 (set by/Users/zioyi /. Pyenv/version)Copy the code
Installs the specified Python version
$Pyenv install 3.10.0 b2Downloading 3.10.0 b2...-> https://downloads.python.org/3.10.0b2.tar.bz2Installing 3.10.0 b2... Installed 3.10.0 b2 to/Users/zioyi /. Pyenv/versions / 3.10.0 b2Copy the code
The global environment specifies the Python version
$Pyenv global 3.10.0 b2
$ pythonPython 3.10.0b2 (default, Jul 29 2021, 09:57:10) [Clang 12.0.5 (clang-1205.0.22.9)] on Darwin Type "help", "copyright", Python 3.10.0 B2 (default, Jul 29 2021, 09:57:10) [Clang 12.0.5 (clang-1205.0.22.9)] "credits" or "license" for more information.>>>
Copy the code
Specify the Python version under the current shell
$ 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.
>>>
Copy the code
Note: Local has a higher priority than global
Uninstall the installed Python version
$Pyenv uninstall pypy3.7-7.3.5Pyenv: remove/Users/zioyi /. Pyenv/versions/pypy3.7-7.3.5? [y | N] y pyenv: pypy3.7-7.3.5 uninstalledCopy the code
See the official command manual for more information
The principle of pyenv
In fact, the secret of PyEnv lies in the second step of installing PyEnv: initializing PyEnv
eval "$(pyenv init -)"
Copy the code
Since this line of command is written in the.zprofile file, it is executed every time you log in to the shell, and its effect is to add pyenv-related paths to the PATH
$ echo $PATH
***:/Users/zioyi/.pyenv/shims:/Users/zioyi/.pyenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:***
Copy the code
When Linux runs a command, it traverses each PATH of the PATH environment variable in order to find the command to be executed. The traversal stops when the first match is found in a directory, so in the PATH environment variable, the earlier PATH has a higher priority than the later PATH.
System default Python is commonly under the/usr/bin directory, and the path/Users/zioyi pyenv /. Pyenv/shims, before it all when we are in the shell to execute the Python command, will now pyenv catalog to find
$ which python
/Users/zioyi/.pyenv/shims/python
Copy the code
We call shim a shim, which acts as a layer of proxy between shell and Python. Pyenv creates shim for various Python version-related commands in the ~/.pyenv/shims directory
$ ls ~/.pyenv/shims2to3 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.7idle3 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- nbexvector pip3 pygmentize python3.10 rst2html4.py send2Trash cpuinfo ipython Jupyter-qtconsole pip3.7pypy3 jupyter-qtconsole pip3.7pypy3 jupyter-qtconsole pip3.7pypy3 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.pyCopy the code
So when we execute python-related commands, we’re actually executing these shim. The contents of these spacers are the same:
$ 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" "$@"
Copy the code
When we run program “param1” “param2″… Pyenv exec “program” “param1” “param2″… . For example, if python -v is executed, pyenv exec python -v is actually executed.
In the pyenv exec command, the pyenv version name is first called to determine the Python version or virtual environment version. The search rules are:
Within the pyenv exec command, pyenv which is called again to determine the path to the executable program. If the previous Pyenv version name determines the Python or virtual environment version, Use either
After determining the executable file path corresponding to the version number, run the following command:
exec -a program "$path" "param1" "param2"
#Note: Execution"path" "param1" "param2", and use program as the program name, which is in the shell$0, sys.argv0 in Python
Copy the code
Execute python -v, for example, to determine the pyenv version for 3.10.0 b2, corresponding to the executable file for ~ /. Pyenv/versions / 3.10.0 b2 / bin/python, execute commands as follows:
The exec - a python ~ /. Pyenv/versions / 3.10.0 b2 / bin/python -vCopy the code
That’s the basic principle of pyenv execution
conclusion
Pyenv is a great way to manage multiple versions of Python. When different projects require different Versions of Python, pyEnv can be easily managed; Pyenv can also be used when we want to try new Python3.10 and are worried about polluting our development environment.