Pyenvについて

## TL; DR
この記事ではPyenvのインストール方法からPythonインタープリターのバージョンの変更まで調べてみました。
調べたきっかけとして、Pyenvを使用して様々なバージョンのPythonをインストールできるということがとても印象的だったので、もっと詳しく知りたいと思ったからです。
いつでも最新版のPythonが使えればいいのですが、Amazon Linux 2023で用意しているLambda用のPythonがほんのちょっとだけ古かったり、機械学習で用いるDockerイメージでは3.10.xでなければ動作保証外だったりすることがあります。
pyenvを用いることでPythonのインストールとバージョン選択が楽になると知ったので、ここにまとめます。

## 概要
Pyenv、Pythonのバージョン管理ツールで、開発環境でのPythonバージョンの切り替えや管理を容易にするためのツールです。以下に、Pyenvの主な利点を紹介します。

### 複数のPythonバージョンの共存
Pyenvを使うと、システムに複数のPythonバージョンをインストールして、それらを簡単に切り替えることができます。これにより、プロジェクトごとに異なるPythonバージョンを使用する場合でも、環境を汚さずに対応できます。

### バージョンの自動切り替え
特定のディレクトリに入ると、自動的にPythonのバージョンが切り替わる機能があります。これは、そのディレクトリに`.python-version`ファイルを置くことで実現できます。

```zsh:terminal
echo "3.8.6" > .python-version
```
この設定により、ディレクトリに入ると自動的に指定したバージョンに切り替わります。

### Pythonのビルドオプションのカスタマイズ
Pyenvは、Pythonをソースからビルドする際のオプションをカスタマイズすることができます。例えば、特定のモジュールを有効にするためのオプションを指定できます。
```zsh:terminal
PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.12.3
```

### プラグインのサポート
Pyenvはプラグインをサポートしており、例えば`pyenv-virtualenv`を使うと仮想環境の管理が可能になります。これにより、プロジェクトごとに依存関係を完全に分離することができます。

### 互換性と拡張性
Pyenvは、多くのオペレーティングシステム（macOS、Linux、Windows Subsystem for Linuxなど）で動作し、幅広いPythonバージョンをサポートしています。また、プラグインを使って機能を拡張することができるため、柔軟性があります。

### 既存のプロジェクトとの互換性
Pyenvは、既存のPythonプロジェクトやツールチェインとの互換性が高く、例えば`pip`や`virtualenv`と一緒に問題なく動作します。また、PyenvはPythonの公式インストーラを使わないため、システムのPython環境を汚さずに新しいバージョンを試すことができます。

## Pyenvについて

## Pyenvのインストール手順

### Mac
### Homebrewがある場合

#### Pyenvのインストール
```zsh:terminal
brew update
brew install pyenv
```

### Homebrewがない場合

#### Pyenvのインストール
下記のコマンドを実行してください。

```zsh:terminal
curl https://pyenv.run | bash
```

### Windows
公式を読むとこれを使ってくださいとのことでした。 https://github.com/pyenv-win/pyenv-win 詳細はこちらをご確認ください。

### インストールの確認

下記の内容が表示されたら正常にインストールができています。
```zsh:terminal
pyenv version
```

## 様々なバージョンのPythonのインストール方法
Pyenvを使用して様々なバージョンのPythonをインストールする方法について、具体的な手順を説明します。

### Pythonバージョンのインストール
Pyenvを使用して、必要なPythonバージョンをインストールします。以下のコマンドで、利用可能なPythonバージョンのリストを取得できます。

```zsh:terminal
pyenv install --list
```
リストからインストールしたいバージョンを選び、以下のコマンドでインストールします。
```zsh:terminal
pyenv install <バージョン番号>
```

### インストールされたPythonバージョンの確認
インストールされたPythonバージョンを確認するには、以下のコマンドを使用します。
```zsh:terminal
pyenv versions
```

### Pythonバージョンの切り替え
インストールされたPythonバージョンを使用するには、以下のコマンドを実行します。

* 全体的なデフォルトバージョンを設定する場合
```zsh:terminal
pyenv global <バージョン番号>
```

* 特定のディレクトリで使用するバージョンを設定する場合
```zsh:terminal
pyenv local <バージョン番号>
```

* 一時的に使用するバージョンを設定する場合
```zsh:terminal
pyenv shell <バージョン番号>
```

### Pythonバージョンの確認
現在使用しているPythonバージョンを確認するには、以下のコマンドを実行します。

```zsh:terminal
pyenv version
```

また、システム全体で使用されているPythonバージョンを確認するには、以下のコマンドを実行します。

```zsh:terminal
python --version
```

### Pythonのアンインストール
不要になったPythonバージョンをアンインストールするには、以下のコマンドを実行します。
```zsh:terminal
pyenv uninstall <バージョン番号>
```

## どんな時に使われる？
Pyenvは、複数のPythonバージョンを簡単に管理・切り替えできるツールで、以下のような場合に特に便利です。

### 複数プロジェクトで異なるPythonバージョンを使用する場合
異なるプロジェクトで異なるPythonバージョンを使用する必要がある場合、Pyenvは非常に役立ちます。例えば、あるプロジェクトではPython 3.11を使用し、別のプロジェクトではPython 3.12を使用したい場合、Pyenvを使ってそれぞれのプロジェクトに適したバージョンを簡単に設定できます。

### 新しいPythonバージョンのテスト
新しいPythonバージョンがリリースされた際に、そのバージョンを試してみたい場合にもPyenvは便利です。既存の環境を壊さずに、新しいバージョンをインストールしてテストすることができます。

### レガシーコードのメンテナンス
古いプロジェクトが特定の古いPythonバージョンでしか動作しない場合、Pyenvを使用するとそのバージョンをインストールして、プロジェクトを問題なくメンテナンスできます。

### 開発環境の標準化
チームで開発を行う場合、Pyenvを使用すると、全員が同じPythonバージョンを使って開発することが容易になります。pyenvを使ってPythonのバージョンを指定しておけば、新しいメンバーがプロジェクトに参加する際も、簡単に開発環境を整えることができます。

### システムPythonと独立した環境の構築
システムにインストールされているPythonバージョンを変更することなく、プロジェクトごとに異なるPythonバージョンを使用できます。これにより、システムの安定性を保ちつつ、柔軟にPython環境を管理できます。

#### 具体的な使用例
##### プロジェクトAでPython 3.10を使用し、プロジェクトBでPython 3.１２を使用したい場合
```zsh:terminal
# プロジェクトAのディレクトリに移動
cd /path/to/projectA
# プロジェクトA用のPythonバージョンを設定
pyenv local 3.10.14

# プロジェクトBのディレクトリに移動
cd /path/to/projectB
# プロジェクトB用のPythonバージョンを設定
pyenv local 3.12.3
```

##### 新しいPythonバージョンのテスト
```zsh:terminal
# Python 3.1２をインストール
pyenv install 3.12.3
# 一時的にPython 3.1２を使用
pyenv shell 3.12.3
```

##### レガシープロジェクトのメンテナンス
```zsh:terminal
# Python 2.7をインストール
pyenv install 2.7.18
# プロジェクト用のディレクトリに移動
cd /path/to/legacy_project
# レガシープロジェクト用のPythonバージョンを設定
pyenv local 2.7.18
```

## まとめ
Pyenvは、複数のPythonバージョンを簡単に管理・切り替えするための強力なツールであり、開発環境を汚さずに異なるバージョンのPythonを共存させることができます。また、自動バージョン切り替え、カスタマイズ可能なビルドオプション、プラグインによる機能拡張など、多くの利点があります。これにより、プロジェクトごとに異なるバージョンや依存関係を管理することが容易であるとわかりました。

## パッケージマネージャーを用いた実践

### poetryでのPythonバージョンの切り替え方法
以下に、Poetryを使用してPythonバージョンを切り替える方法を説明します。

#### プロジェクトで使用するPythonバージョンを指定する
Poetryプロジェクトで使用するPythonバージョンを指定するには、`pyproject.toml`ファイルを編集します。このファイルには、プロジェクトのメタデータや依存関係の情報が含まれています。
```python:pyproject.toml
[tool.poetry]
name = "your-project-name"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]

[tool.poetry.dependencies]
python = "^3.１２"
```
上記の例では、Python 3.12.xを使用するように指定しています。

#### Poetryの環境を更新する
Pythonバージョンを指定した後、以下のコマンドを実行してPoetryの環境を更新します。

```zsh:terminal
poetry install
```
これにより、指定したPythonバージョンに基づいて環境がセットアップされます。

#### 特定のPythonバージョンを使用する
もし、特定のPythonバージョンを使用する必要がある場合は、pyenvで特定のバージョンのPythonをインストールしておき、poetryのuseコマンドでそれを指定します。
```zsh:terminal
pyenv install 3.12.3
poetry env use 3.12.3
```
※pythonのバージョンを指定する時にパスを指定する必要はありません。

#### Pythonバージョンの確認
現在のプロジェクトで使用されているPythonバージョンを確認するには、以下のコマンドを実行します。
```zsh:terminal
poetry env info
```
このコマンドは、仮想環境に関する情報を表示し、使用されているPythonのパスやバージョンを確認できます。

### ryeでのPythonバージョンの切り替え方法

#### Ryeのセットアップ
まず、Ryeをインストールした後、環境変数の設定を行います。以下のコマンドを実行して設定を有効にします。
```zsh:terminal
source ~/.rye/env
```


#### プロジェクトごとのPythonバージョンの設定
特定のプロジェクトで使用するPythonバージョンを設定するには、プロジェクトのルートディレクトリで以下のコマンドを実行します。

```zsh:terminal
rye use 3.12.3
```
このコマンドにより、プロジェクトディレクトリに.python-versionファイルが作成され、指定したPythonバージョンが設定されます。

#### Pythonバージョンの確認
現在使用しているPythonバージョンを確認するには、以下のコマンドを実行します。

```zsh:terminal
rye which python
```
または、現在のプロジェクトで設定されているバージョンを確認するには以下のコマンドを使います。

#### 【参考】Pythonバージョンのインストール
この記事ではPyenvについて紹介をしていますが、Ryeを使って特定のPythonバージョンをインストールすることもできます。例えば、Python 3.12.3をインストールする場合は以下のコマンドを使用します。

```zsh:terminal
rye install python@3.12.3
```

## パッケージマネージャーについて過去にまとめた記事

https://qiita.com/hiseumn/items/5baa2eb44885dffc9bac

https://qiita.com/hiseumn/items/f5427a1ea5912383e525

## 参考資料

https://github.com/pyenv/pyenv

https://github.com/pyenv-win/pyenv-win