🐍

Pythonの仮想環境構築

2022/03/26に公開

はじめに

Pythonにおける仮想環境構築について、python で仮想環境を構築するツールは以下のようにたくさんの種類があります。はじめに各種仮想環境作成ツールについての簡単な説明を行います。

Python の仮想環境作成ツールの主な分類について。

  1. Python(インタプリタ)のバージョン切り替えを行うもの
  2. パッケージ切り替えを行うもの
  3. 2の機能に加えて独自のパッケージ管理機能を有するもの(pip以外のパッケージ管理を利用可能なもの)
1. インタプリタ 2. パッケージ 3. 独自パッケージ管理
venv
virtualenv
pyenv
pyenv-virtualenv
pipenv
anaconda

ツールの比較や歴史的経緯は以下の記事が参考になります。

https://vaaaaaanquish.hatenablog.com/entry/2021/03/29/221715#Anacondaなど他ツール

https://zenn.dev/mook_jp/articles/6815e6806b516f

実行環境

  • OS: Ubuntu 20.04.4 LTS (Focal Fossa)
  • shell: zsh 5.8 (x86_64-ubuntu-linux-gnu)

pyenvとは

pyenv は、複数のバージョンの Python を簡単に切り替えることができます。
pyenvshell を常に監視して、ユーザーが python を利用する時に仮想環境の python を渡すことで、様々なバージョンの python を切り替えて利用できるという仕組みです。

https://github.com/pyenv/pyenv

もともとは rbenv と呼ばれる ruby 用の仮想環境構築ツールから派生して作られています。

https://github.com/rbenv/rbenv

この記事では、pyenv では基本的にパッケージをインストールせず、利用したいPythonバージョンを切り替えるために使います。パッケージ管理には PipenvPoetry などを使うことを想定しています。

Pyenv本体のインストール

pyenvをインストールしていきます。

依存関係にあるライブラリをインストール

はじめに、依存関係のあるライブラリをインストールしていきます。

zsh
sudo apt update; sudo apt install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev \
git

pyenvをダウンロード

gitコマンドで pyenv をダウンロード(clone)します。

zsh
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
git cloneコマンドについて
zsh
git clone <ダウンロード元のレポジトリ> <ダウンロードするディレクトリ>

上記のコマンドでは pyenvの公式レポジトリから~./pyenv に保存しています。
~$HOME はホームディレクトリを表します

ダウンロード場所を変更する場合は、以下のpathを通す作業時にダウンロード場所を指定して下さい。

PATHを通す

先程ダウンロード(clone)したディレクトリ内にある、pyenvの実行ファイルへのPATHを通します。この作業を行うことで、pyenvコマンドが利用可能になります。

zsh
# 1. "$HOME/.pyenv" は先程ダウンロードしたディレクトリ path 入力する
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc

# 2. Pathを通す
# 環境変数 $PATH に先程ダウンロードしたディレクトリ内の実行ファイルを登録する
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc

# 3. pyenvコマンドを初期化する
echo 'eval "$(pyenv init --path)"' >> ~/.zshrc
シェルの種類を確認する
bash
echo $SHELL
Bashを利用している場合
bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc

PATHを追加した ~/.zshrc または ~/.bashrc を再読込します。

zsh
source ~/.zshrc
Bashを利用している場合
bash
source ~/.bashrc

使い方

インストールが完了していることを確認するため、「pyenv」のバージョンを確認します。

zsh
pyenv -v

バージョンが表示されれば、PyenvがインストールされておりPathが通っています。

インストール可能なPythonのバージョンを表示

インストール可能な「python」のバージョンを表示します。

zsh
pyenv install --list

Python をインストール

python` のバージョンを指定してインストールしていきます。

zsh
pyenv install 3.10.0

インストールが完了したか確認する。
インストールが正常に完了していたら、先程インストールした3.10.0が表示されます。
現在利用している「python」の頭に*が表示されています。

zsh
pyenv versions
* system (set by /home/mook/bin/pyenv/version)
  3.10.0

Pythonのバージョンを変更

  • 現在のユーザーで利用するpythonのバージョン変更します。(全ディレクトリ)
zsh
pyenv global 3.10.0 # Python 3.10.0を利用する
  • 現在のディレクトリで利用するバージョンを変更する
zsh
pyenv local 3.10.0 # Python 3.10.0を利用する

設定中のPythonのバージョンを表示

現在設定中の「python」のバージョンを表示する。
デフォルトではシステム用にインストールされている「python」のバージョンが表示されます。

  • pyenvでインストールされているPythonのバージョンを一覧表示する。有効化されているバージョンは行頭に*(アスタリスク)がついています。
zsh
pyenv versions
  • pyenv有効になっているPythonのバージョンを表示する。
zsh
pyenv version
  • OSbashzsh)で有効になっている python のバージョンを確認する。
zsh
python -V
  • 有効になっているPythonの実行ファイルがある場所を表示
zsh
which python

pyenvの各バージョンのインストール場所について

pyenv install <version>コマンドでインストールしたPythonは以下の場所に保管されています。$HOME/.pyenvは最初に pyenv をダウンロードした場所です。

zsh
$HOME/.pyenv/shims/               # pyenvの仕組みの核。
          |-/versions             # インストールしたPythonの格納場所
                   |-/2.7.8/      # Python 2.7.8
                   |-/3.4.2/      # PYthon 3.4.2
                   |-/pypy-2.4.0/ # PYPY 2.4.0
          |-/version              # globalで使うpythonのバージョン情報ファイル

pyenv でバージョン切り替えができない場合

バージョンの切り替えができない場合は、以下のような箇所を確認すると良いです。

1. pyenvコマンドが command not found となるとき

PATHが通っていません。pathが登録されているか確認しましょう。
pyenvのPATHが通っている場合は、 echo $PATH コマンドを実行した時に、<pyenvをダウンロードしたディレクトリ>/binが表示されます。
出力はディレクトリのPATH1:ディレクトリのPATH2:...のように表示されます。

zsh
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
出力を見やすく改行
bash
echo $PATH
/usr/local/sbin:
/usr/local/bin:
/usr/sbin:
/usr/bin:
/sbin:
/bin:
/usr/games:
/usr/local/games:
/snap/bin

ダウンロードした、pyenvのディレクトリが表示されていない場合はPATHを通すをご確認くださいを確認してください。

2. pyenvコマンドは使えるが、 Pythonのバージョンが切り替わらない
pyenvの初期化に失敗しています。echo $PATHを実行し、<pyenvをダウンロードしたディレクトリ>/bin/shimsが表示されるか確認します。

zsh
echo $PATH
/home/mook/.pyenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

通っていない場合は、以下のコマンド実行します。

zsh
eval "$(pyenv init --path)"

これで python -V で有効になっていれば大丈夫です。
ログイン時に有効になるように以下の、コマンドを実行してください。

zsh
echo 'eval "$(pyenv init -)"' >> ~/.zshrc
bashの場合
bash
echo 'eval "$(pyenv init -)"' >> ~/.bashrc

※ その他詰まったことがあればコメントください。

よくあるパターン

初めて pyenv をインストールして使うまで。

zsh
# pyenvはインストールされている
$ pyenv -v
pyenv 2.2.5-9-g72757562

# インストールされているバージョンを表示する
$ pyenv versions
* system (set by /home/mook/.pyenv/version)

# pythonのバージョンを確認する。まだpyenvでインストールしていないからだと思い込む
$ python -V
zsh: command not found: python

# なぜか python3 コマンドは利用できる
$ python3 -V
Python 3.8.10

# python3コマンドはどこにインストールされている?
# OSに標準インストールされているPython
$ which python3
/usr/bin/python3

# とりあえず、pythonをインストールしてみる
$  pyenv install 3.8.10
Downloading Python-3.8.10.tar.xz...
-> https://www.python.org/ftp/python/3.8.10/Python-3.8.10.tar.xz
Installing Python-3.8.10...
Installed Python-3.8.10 to /home/mook/.pyenv/versions/3.8.10

# ちゃんとインストールされている
$ pyenv versions
* system (set by /home/mook/.pyenv/version)
  3.8.10

# インストールされたpythonを有効化してみる
$ pyenv global 3.8.10

# ちゃんと有効化されている
$ pyenv versions
  system
* 3.8.10 (set by /home/mook/.pyenv/version)

# まだ python コマンドは使えない、ここで焦る。
$ python -V
zsh: command not found: python

# python3 コマンドは使える。
# 以下のような、思考が頭をよぎります。
#   - `python`コマンドが使えないだけだと思い込む。
#   - 出力されたバージョンは先程インストールしたものだし大丈夫だろう。
$ python3 -V
Python 3.8.10

大抵このパターンはPythonの新バージョンが出て、新機能を試したりすると、有効になっていないことに気づきます。

# 初めて使う時はちゃんとコマンドの場所を確認しましょう
$ which python3

登録されているPATHを確認してみましょう

  1. pyenvコマンドにPATHが通っていない場合
zsh
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
  1. pyenvにPATHが通っている場合(pyenvの初期化ができていない場合)
    /home/mook/.pyenv/bin(pyenvをダウンロードした場所)が追加されています。
zsh - pyenvにPATHが通っている場合
echo $PATH
/home/mook/.pyenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
  1. pyenvが正常に有効化されている
    /home/mook/.pyenv/shimsが追加されています。
zsh - pyenvが正常に有効化されている
echo $PATH
/home/mook/.pyenv/shims:/home/mook/.pyenv/bin:/home/mook/.pyenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

pyenvのチートシート

各オプションは以下のように利用します。

zsh
pyenv <オプション>
オプション 説明
--version pyenvのバージョンを表示します
commands 利用可能なpyenvのコマンドを一覧表示します。--helpの説明がないコマンド一覧が表示されます。
exec 選択されたPythonのバージョンで実行ファイルを実行する。例:pyev exec pip install Flaskなどの実行可能ファイルを実行することができる。linuxではBourne-Again shell script(Bash Script)などを実行することができます。pip自体も中身はBash Scriptです。なお、実行時はコマンドとして登録されている場合はそのまま使えますが、ファイル形式のものを利用する場合は、pyenv exec ./test.shなどのように./を頭につけないと実行できません。
shell 現在のシェルのみに有効なPythonのバージョンを設定または表示
local ローカル(特定ディレクトリで有効)なPythonのバージョンを設定または表示
global グローバル(全ディレクトリで有効)なPythonのバージョンを設定または表示
help コマンドの一覧と説明を表示する
hooks 指定されたpyenvコマンドのフックスクリプトを一覧表示します。https://github.com/pyenv/pyenv/wiki/Authoring-plugins#pyenv-hooks
init pyenvのためのシェル環境の設定。eval "$(pyenv init --path)"~/.bashrc等へ記載することでpythonを実行する時にpyenv側でコマンドを受け取ってpyenvで管理しているバージョンで実行してくれるようになります。
install pythonのバージョンを指定してインストールできます。
uninstall pythonのバージョンを指定してアンインストールできます。
prefix pythonのバージョンを表示する
rehash 新しいバージョンをインストール後に実行し、pyenv shimsの更新します。pyenv/shims/内にファイルを生成します。
root shimsversionsディレクトリなどが格納されているpyenvのインストール場所を表示します。
shims pyenv用のshims(バージョン間の差異を埋めるファイル)をリスト表示する
version 現在有効なpythonのバージョンとpyenv version-fileの内容が表示される。
version-file globalの場合はpyenv/versionとなり、localの場合はlocalを実行したディレクトリ配下に.python-versionファイルが作成されそのPATHが表示される。
version-name 現在有効なpythonのバージョンが表示される。
versions インストール済みのpythonのバージョン一覧と設定中のバージョンを表示する
whence 与えられた実行ファイルを含む全てのPythonのバージョンをリストアップする
which 実行ファイルのフルパスを表示する

Discussion