Last Updated: 2/6/2024, 5:44:57 AM

WARNING

環境は macOS での解説になります。

# venv で仮想環境を作る。

pip install する
ディレクトリを分けます。

# 1. 仮想環境を作るってなに?

「仮想環境を作る」と大げさに言いましたが、 簡単に言えば pip install するディレクトリを新しく作るだけです。

pip install したパッケージはどこに保存されているのでしょうか? site-packages と言う名前のディレクトリに保存されます。

venv を使うと、pip でインストールしたパッケージやモジュールを保存する site-packages というディレクトリを新しく作ることができます。

site-packages の居場所は、sys.path から簡単に調べることができます。

import sys
print(*sys.path, sep="\n")
>>> import sys
>>> print(*sys.path, sep="\n")

/usr/local/Cellar/[email protected]/3.8.1/Frameworks/Python.framework/Versions/3.8/lib/python38.zip
/usr/local/Cellar/[email protected]/3.8.1/Frameworks/Python.framework/Versions/3.8/lib/python3.8
/usr/local/Cellar/[email protected]/3.8.1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/lib-dynload
/usr/local/lib/python3.8/site-packages  <--- ここに注目
>>> 

Python は、パッケージまたはモジュールを import する時、 sys.path に保存されたパスを順番に検索しています。 sys.path については以下の記事で見てきました。 ここでは説明は省略させていただきます。

ここで調べられた site-packages 配下にあるファイルと pip list した結果を見比べてみてください。 だいたいは一致するはずです。

ls -la /usr/local/lib/python3.8/site-packages
pip3 list
$ ls -la /usr/local/lib/python3.8/site-packages
total 320
drwxr-xr-x  28 UFO  admin     952  2 14 21:28 .
drwxr-xr-x   3 UFO  admin     102  9 30  2018 ..
drwxr-xr-x  19 UFO  admin     646  2 14 21:28 pbr
-rw-r--r--   1 UFO  admin   32452  2 14 21:28 six.py
drwxr-xr-x  15 UFO  admin     510  2 14 21:28 stevedore
...
$
$ pip3 list
pbr==5.1.2
six==1.12.0
stevedore==1.30.0
...
$ 
まとめ

仮想環境を作るとは
site-packages ディレクトリを
新しく作ること

# 2. なんで仮想環境が必要なの?

なんで仮想環境が必要なのでしょうか? 言い換えれば、なんで pip install するディレクトリ site-pacakges を複数作る必要があるのでしょうか?

例えば Django で作っているアプリケーションのためにインストールしたいパッケージもあります。 また Flask で作っているアプリケーションのためにインストールしたいパッケージもあります。 それらのパッケージを一箇所で管理するのは、いろいろと怖いものがあります。

Virtualenv (opens new window)

いま、あなたは version 1 の LibFoo を必要とするアプリケーションを持っていて、一方で別のアプリケーションでは version 2 が必要な状況を考えて見てください。 どうやって2つのアプリケーションを使いますか?
Imagine you have an application that needs version 1 of LibFoo, but another application requires version 2. How can you use both these applications?

もし全てを /usr/lib/python2.7/site-packages (あるいは、あなたのプラットフォームの標準場所がなんであろうとも) にインストールした場合、 アップグレードしてはいけないアプリケーションを意図せずアップグレードしてしまうような状況に簡単に陥ってしまうでしょう。
If you install everything into /usr/lib/python2.7/site-packages (or whatever your platform’s standard location is), it’s easy to end up in a situation where you unintentionally upgrade an application that shouldn’t be upgraded.

# ◯ venv の歴史

上記は virtualenv というライブラリのドキュメントからの引用になります。 なぜ virtualenv という別のライブラリの文章を引用したのでしょうか?

venv はもともと virtualenv と呼ばれていたライブラリが、PEP 405 によって標準ライブラリに採用されたものらしいです。 ただ virtualenv の全部ではなく、一部らしいです。 以下は venv のドキュメントからの引用です。

virtualenv は、個別の Python の環境を作成するツールです。 Python 3.3 以降、そのサブセットは venv モジュールの下の標準ライブラリに統合されています。 venv モジュールは、このライブラリのすべての機能を提供しているわけではありません。
virtualenv is a tool to create isolated Python environments. Since Python 3.3, a subset of it has been integrated into the standard library under the venv module (opens new window). The venv module does not offer all features of this library, to name just a few more prominent:
venv — Creation of virtual environments (opens new window)

そのほかの背景などは PEP 405 に経緯等が書かれています。

# ◯ そのほかの様々なツール

ここでは venv について見ていきます。

他にも pyenv, pipenv, poerty など色々ライブラリがあるのですが、 正直、どう言うものかあまりわかっていません。

Python 本体のバージョンを切り替えるライブラリもあるそうですが、ここではインストールしません。 pyenv, poetry, pipenv とライブラリはあるのですが、 そこまでのものは必要ないのではないかという意見を見たためです。 これをすれば良くなるよりも、これは要らないという情報の方が本当に助かります。 ありがとうございます。

# 3. 仮想環境の作り方

動作の詳細は置いておいて、とりあえず、作成から削除までの全体像を駆け足で見てみます。

  • 仮想環境を作成する。
  • 仮想環境を有効にする。
  • 仮想環境を無効にする。
  • 仮想環境を削除する。

# Step0. 移動

プロジェクトのルートディレクトリに移動します。

cd /Users/user/プロジェクトへのパス/

# Step1. 仮想環境を作成する。

venv と言う名前がつけられていることが多いです。

# python3 -m venv 仮想環境名
python3 -m venv venv

venv ディレクトリが作成されます。

$ ls -la
...
venv
$

# Step2. 仮想環境を有効にする。

# 仮想環境を有効にします。
. venv/bin/activate

先頭に (venv) という文字がつきます。

$ # 仮想環境を有効にします。
$ . venv/bin/activate
(venv) $

# Step3. 仮想環境を無効にする。

# 仮想環境を無効にします。
deactivate

先頭の (venv) という文字が消えます。

(venv) $ # 仮想環境を無効にします。
(venv) $ deactivate
$

# Step4. 仮想環境の削除する。

ディレクトリを削除すればそれで OK です。

rm -r venv

# 4. Pytohn のバージョンの分け方

Python 2, 3 といったバージョンを分ける際には、Python のコマンドを切り替えて実行していきます。

# Python 2 の venv を使うと 
# Python 2 の仮想環境が作られます。
python  -m venv venv

# Python 3 の venv を使うと
# Python 3 の仮想環境が作られます。
python3 -m venv venv

# 5. 動作の確認 - 概要編

仮想環境にウェブアプリケーションフレームワークである Flask をインストールして、 動作の概要を確認して見たいと思います。

# Step1. スクリプトを作成します。

Hello, World! という文字を返すんだな、 ということだけ押さえておいていただけると幸いです。

vim hello.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello, World!'

# Step2. Flask を起動します。

#
# $ シェルにコピぺで動きます。
# 

# 仮想環境を作成する。
python3 -m venv venv

# 仮想環境を有効にする。
. venv/bin/activate

# Flask をインストールする。
pip install flask

# flask run コマンドで起動する
# スクリプトを指定する。
export FLASK_APP=hello.py

# Flask を起動する。
flask run

# Step3. 確認する。

http://127.0.0.1:5000/ にアクセスして、 Hello, world! と表示されているか確認して見ましょう。

# Step4. Flask を停止する。

ターミナルで Ctrl + C を押下して Flask を停止します。

# Step5. pip list で一覧を表示する。

Flask という文字が見えました。

(venv) $ pip list
Package      Version
------------ -------
Click        7.0    
Flask        1.1.1    <--- Flask がありました。
...
(venv) $ 

# Step6. 仮想環境を無効にする。

deactivate

# Step7. 再度 pip list で一覧を表示する。

Flask という文字は見あたりせん。

$ pip3 list
Package    Version
---------- -------
pip        19.3.1 
setuptools 42.0.2 
wheel      0.33.6 
$ 

そのため対話モード >>> から import もできません。

import flask
>>> import flask
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'flask'
>>>

# Step8. 再度 Flask を起動する。

flask コマンドはないと弾き返されます。

$ flask run
-bash: flask: command not found
$ 
まとめ

仮想環境を無効にすると、
import やコマンドが
使えなくなりました。

# 6. 動作の確認 - 詳細編

仮想環境を無効にすると import flask できなくなったり、 flask run コマンドが使えなくなりました。

なぜでしょうか? Python の sys.path と OS の $PATH が変化したからです。 仮想環境を有効にすると sys.path と $PATH に venv へのパスが追加されます。 無効にすると venv へのパスが削除されます。

# 6.1. 仮想環境を有効にして

# $ シェルにコピぺで動きます。


# Step0. 仮想環境を有効にする。
. venv/bin/activate

# Step1. OS の $PATH を表示する。
echo "${PATH//:/$'\n'}"

# Step2. Python の sys.path を表示する。
python3
import sys
print(*sys.path, sep="\n")

いずれも venv という文字が見えます。

(venv) $ # Step1. OS の $PATH を表示する。
(venv) $ echo "${PATH//:/$'\n'}"

... 前略

/Users/user/プロジェクトへのパス/venv/bin
                            ^^^^ <--- ココに注目
... 後略

(venv) $ 
(venv) $ # Step2. Python の sys.path を表示する。
(venv) $ python3
>>> import sys
>>> print(*sys.path, sep="\n")

... 前略

/Users/user/プロジェクトへのパス/venv/lib/python3.8/site-packages
                            ^^^^ <--- ココに注目
... 後略

>>> 

# 6.2. 仮想環境を無効にして

同じことを仮想環境を無効にして表示させると、どうなるでしょうか?

# $ シェルにコピぺで動きます。


# Step0. 仮想環境を無効にする。
deactivate

# Step1. OS の $PATH を表示する。
echo "${PATH//:/$'\n'}"

# Step2. Python の sys.path を表示する。
python3
import sys
print(*sys.path, sep="\n")

venv という文字は見当たらなかったはずです。

まとめ

仮想環境を有効にすると、
sys.path と $PATH が変化する。

以上になります。 ありがとうございました。