MacにPythonとpipの環境を構築する

## はじめに

最近改めてPythonを（というかAIを）学ぼうと思い立ち、まずはPythonのインストールから始めたのですが、環境整備の選択肢で迷うところが何点かありました。
そこで自分の理解をまとめるためにも久々に記事を書くことにしました。
間違い、補足などありましたら、お手柔らかにご指摘くださいませ。
### 本記事のスコープ
Pythonとpipが動作する環境構築するところまでを取り上げます。
### 本記事の対象者
初めて、「Pythonとpipが動作するMacの環境」構築するけど、選択肢が多そうで迷っている方。
### 本記事で触れないこと
本記事で触れた他にも選択肢はありそうですが、自分は選択しないしおススメもしないので記載しません。


## 環境整備のフロー

「選択肢が多そうで迷っている方」に対するアプローチとして、フローチャートで進んでいく形式で書いてみました。
選択した処理をタップすると、記事の本文に飛ぶようにしたかったのですが、どうもうまくいかないので本文は右の目次から選んでください。

なお、「グローバル環境のPythonをインストールする」は「おススメ」しないですが一応入れています。

```mermaid

flowchart
  Start-->isEachPythonVersion
  isEachPythonVersion-->|はい| pyenv
  isEachPythonVersion-->|いいえ| GlobalInstall
  pyenv-->isPipVirtual
  GlobalInstall-->isPipVirtual
  isPipVirtual-->|はい| isPipVirtualDepend
  isPipVirtualDepend-->|紐付けする|PipVirtualenv
  isPipVirtualDepend-->|独立|PipVenv
  isPipVirtual-->|いいえ|End
  PipVenv-->End
  PipVirtualenv-->End

  


Start([Python環境整備])

isEachPythonVersion{Pythonのバージョンを切り替えて使い分けたい}
isPipVirtual{pipを仮想環境で使いたい}
isPipVirtualDepend{pip仮想環境をPythonのグローバルバージョンと紐づけるか、独立か}

GlobalInstall([グローバル環境のPythonをインストールする])
pyenv([pyenvでPythonをバージョン別に管理する])
PipVirtualenv([pipをグローバルバージョンに紐づけられた仮想環境で実行する])
PipVenv([pipをグローバルバージョンから独立した仮想環境で実行する])
End([End])

%% クリック設定 %%
click GlobalInstall "[A](https://qiita.com/BlueEventHorizon/items/a51d83f7339b28d67efb#%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E7%92%B0%E5%A2%83%E3%81%AEpython%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)"
click PipVirtualenv "[B](https://qiita.com/BlueEventHorizon/items/a51d83f7339b28d67efb#pip%E3%82%92%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AB%E7%B4%90%E3%81%A5%E3%81%91%E3%82%89%E3%82%8C%E3%81%9F%E4%BB%AE%E6%83%B3%E7%92%B0%E5%A2%83%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B)"
click PipVenv "[B-2](https://qiita.com/BlueEventHorizon/items/a51d83f7339b28d67efb#pip%E3%82%92%E7%8B%AC%E7%AB%8B%E3%81%97%E3%81%9F%E4%BB%AE%E6%83%B3%E7%92%B0%E5%A2%83%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B)"
click pyenv "[C](https://qiita.com/BlueEventHorizon/items/a51d83f7339b28d67efb#pyenv%E3%81%A7python%E3%82%92%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E5%88%A5%E3%81%AB%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B)"
```






## グローバル環境のPythonをインストールする

非常にシンプルなインストール方法ですが、Pythonのバージョンを切り替えるのが困難です。
利用者によってはバージョン切り替えは頻繁に起こりそうなので、この方法は採用しない方が良さそうです。

```zsh:コマンドラインで実行
brew install python
```
上記でHomeBrewでPythonをインストールします。
ARM系Macであれば、 `/opt/homebrew/bin/python3` あたりにインストールされています。

```zsh:.zshrcに記述
export PATH="$(brew --prefix python)/libexec/bin:$PATH"
```
上記でインストールしたpython3にパスを通します。
これによって

```zsh: コマンドラインで実行
python --version
```
としてもちゃんとバージョンが表示される様になりますので確認してください。

ただし、
```zsh: コマンドラインで実行
pip install langchain
```
などと打つとエラーが発生します。

これについては、 [pipを仮想環境で使う](#pipを仮想環境で使う) をご覧ください。






## pyenvでPythonをバージョン別に管理する

### pyenv のインストール

```zsh:コマンドラインで実行
brew install pyenv
```

インストールは、上記でできます。

### pyenv の初期設定

```zsh:.zshrcに記述
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
```

zsh:.zshrcに上記を記述してください。

```zsh:コマンドラインで実行
source ~/.zshrc
```

ターミナルを再起動しても良いですが、上記で設定が反映されます。

```zsh: コマンドラインで実行
# インストール可能なPythonのバージョン
pyenv install --list

# バージョン3.13.0をインストール
pyenv install 3.13.0

# グローバルのPythonバージョンを切り替える
# システム全体で使用するPython バージョンを設定します。特定のディレクトリで pyenv local で上書きされない限り有効です。
pyenv global 3.13.0

# ローカルのPythonバージョンを切り替える
# 現在のディレクトリのみで使用する Python バージョンを設定します。この設定は .python-version ファイルとして保存されます。
pyenv local 3.9.21
```
よく使うコマンドを上記に挙げました。バージョンの部分は適当に読み変えてください。

詳細は、[こちらの記事](https://qiita.com/teri_man95/items/b15fd8f1964612331be2)などをご覧ください。

## pipとは

pipは、Pythonで使用されるパッケージ管理ツールです。
公式のパッケージリポジトリである[PyPI（Python Package Index）](https://pypi.org/)からパッケージを簡単にインストール、アップデート、アンインストールするために使われます。


### pipエラー

```zsh: コマンドラインで実行
pip install langchain
```
などと打つと下記の様なエラーが発生します。

```text

× This environment is externally managed
╰─> To install Python packages system-wide, try brew install
    xyz, where xyz is the package you are trying to
    install.
    
    If you wish to install a Python library that isn't in Homebrew,
    use a virtual environment:
    
    python3 -m venv path/to/venv
    source path/to/venv/bin/activate
    python3 -m pip install xyz
    
    If you wish to install a Python application that isn't in Homebrew,
    it may be easiest to use 'pipx install xyz', which will manage a
    virtual environment for you. You can install pipx with
    
    brew install pipx
    
    You may restore the old behavior of pip by passing
    the '--break-system-packages' flag to pip, or by adding
    'break-system-packages = true' to your pip.conf file. The latter
    will permanently disable this error.
    
    If you disable this error, we STRONGLY recommend that you additionally
    pass the '--user' flag to pip, or set 'user = true' in your pip.conf
    file. Failure to do this can result in a broken Homebrew installation.
    
    Read more about this behavior here: <https://peps.python.org/pep-0668/>

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
```

と怒られます。
`--break-system-packages`
を使うとこのエラーはパスすることができそうですが、後々面倒なことになりそうなので、他の方法を選択します。


### PEP 668 とは

> Read more about this behavior here: <https://peps.python.org/pep-0668/>

とありますが、

https://peps.python.org/pep-0668/
こちらを見ると、
```
この PEP は歴史的な文書です。最新の標準仕様であるExternally Managed Environments は、 PyPA 仕様ページで管理されています。
```
などと出てきます。
PyPAとは、Pythonのパッケージングエコシステムを標準化・最適化するために定められた仕様やガイドラインの集合体です。
PEP 668はその一部であり、brewなどのPackage管理システムからpipを分離し、仮想環境内でインストールやバージョンを管理するための仕組みの様です。



## pipをグローバルバージョンから独立した仮想環境で実行する

`venv` を使います。
`venv`は、Pythonに組み込まれているので、そのまま実行できます。

独立した仮想環境ですが、仮想環境を作成したときに選択されているPythonのバージョンを前提とした環境になるので、注意が必要です。
下記の `myenv` といった仮想環境の名前にはバージョンも併記しておいた方が分かりやすいかもしれません。

```zsh: コマンドラインで実行
# myenv といういう名前で仮想環境を作成する
python -m venv myenv

# 仮想環境をアクティブにする
source myenv/bin/activate

# 必要なパッケージをインストール
python -m pip install langchain

# 仮想環境を終了
deactivate

```

`python -m venv myenv` を実行したディレクトリにmyenvディレクトリが作成されていますので、 仮想環境は`rm -Rf` で削除可能です。


### pyenvとの関係

pyenvでPython バージョンを切り替えて `python -m venv myenv` を実行すると、異なる Python バージョンごとに独立した`myenv`仮想環境を作ることができます。
ただし `myenv` はただのディレクトリなので、ディレクトリとして被らない様に配慮が必要です。（親のディレクトリを変えるか、`myenv`の名前を変えるか）


## pipをグローバルバージョンに紐づけられた仮想環境で実行する

`pyenv virtualenv` を使います。
`pyenv virtualenv` は、pyenv で利用できるツールで、pyenv で管理される Python バージョンをベースに仮想環境を作成します。


```zsh: コマンドラインで実行
# 現在のPythonバージョンのためのvirtualenvをインストールする
python -m pip install virtualenv

# virtualenvのインストールをzshに反映する
source ~/.zshrc

# myenv といういう名前で仮想環境を作成
python -m virtualenv myenv

# 仮想環境をアクティブにする
source myenv/bin/activate

# 仮想環境を終了
deactivate
```



## pipxについて

[この記事](https://devops-blog.virtualtech.jp/entry/20240603/1717382530)などを参照してください。