【Python】【Linux】pyenvを使用した環境構築

# 0. はじめに

pyenvのドキュメントを主に参考としています。

## 0.1 目的

Pythonの環境構築にあたり、バージョン管理が必要となったので`pyenv`を用いた環境構築について説明します。躓きやすい場所もあったので説明します。

:::note warn
英語を読むのが億劫でない方は，[`README`](https://github.com/pyenv/pyenv/#readme)を読むことを推奨します。
:::

## 0.2 前提条件

- Ubuntu 22.04.3 LTS

`README`を見る限り，`Debian`，`Mint`も同様です。
また，`WSL`でもディストリビューションが同じであれば問題ないです。

https://github.com/pyenv/pyenv/#readme

# 1. 環境構築

## 1.1 環境構築方法の選択[^1]

pythonに関しての環境構築選択には様々な方法があります。
本記事のような`pyenv`や`venv`，`Potery`など。
これらの中で選択を迷う場合は以下の**Kenta Nakamura氏**の記事を参考にするといいかと思います。

https://qiita.com/c60evaporator/items/b6a7394231d1e768ce64

今回の状況はパッケージのバージョン管理は必要ないのでバージョン管理である`pyenv`を選択しました。

## 1.2 環境構築[^2][^3]

1. `pyenv`を使用するための環境構築を行います。
    この事前環境構築を忘れると躓きます。
    ```sh
    sudo apt install build-essential libssl-dev zlib1g-dev \
        libbz2-dev libreadline-dev libsqlite3-dev curl \
        libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
    ```
2. `pyenv`をインストールします。
   1. `git`からクローンします。
        ```sh
        git clone https://github.com/pyenv/pyenv.git ~/.pyenv
        ```
   2. `pyenv`高速化を行います。（失敗しても動きはします。）
        ```sh
        cd ~/.pyenv && src/configure && make -C src
        ```
3. `shell`の設定を行います。
    どちらかの方法で行います。
   1. 直接入力をする方法
        ``` : ~/.bashrc
        export PYENV_ROOT="$HOME/.pyenv"
        command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
        eval "$(pyenv init -)"
        ```
   2. shellから入力する方法
        ```bash
        echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
        echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
        echo 'eval "$(pyenv init -)"' >> ~/.bashrc
        ```
4. 変更の反映を行います。
    方法は２つあります。
   1. 再起動
        ```bash
        sudo reboot
        ```
   2. `source`コマンド（`.`を使用しても問題ない）
        ```bash
        source ~/.bashrc
        ```
5. pyenvのバージョンを確認します。
    ```bash
    pyenv --version
    ```

バージョンが返ってきたら環境構築は完了です。

# 2. pyenvを使用したPythonのインストール

## 2.1 インストール

1. pyenvでインストールできるバージョンを確認します。
    ```Bash
    pyenv install --list
    ```
2. インストールします。
    ```Bash
    pyenv install version_name
    ```
    今回は`pyenv install 3.9.13`と指定しました。
3. インストールされたか確認します。
    ```Bash
    pyenv versions
    ```
    ```Bash:出力
    * system (set by ~/.pyenv/version)
    3.9.13
    ```


## 2.2 バージョン設定

バージョンを指定する方法を説明します。

1. 全体（グローバル）で指定する方法
    ```Bash:global
    pyenv global version_name
    ```
2. ディレクトリで指定する方法
    ```Bash:local
    pyenv local version_name
    ```

最後に，バージョンを確認します。
このときに指定したバージョンが返ってくれば完了です。
```Bash
pyenv version
```
また，指定したバージョンはバージョンを指定したディレクトリ直下に`.python-version`のファイルが作成され，そこに記述されます

今回は，以下のように行いました。
```Bash
cd ~/Test
pyenv local 3.9.13
```
## 2.3 パッケージのインストール

`pip list`で、バージョンごとにインストールされたパッケージの確認ができます。
初期状態は以下のようになっています。

```bash: pip list
Package    Version
---------- -------
pip        23.3.1
setuptools 58.1.0
```

パッケージのインストールは`pyenv`を用いない時と同じです

```bash
pip install package_name
```

今回は`Numpy`をインストールしてみます。

``` bash
pip install numpy
```

インストール後，再び`pip list`を確認すると以下のように`Numpy`が追加されています。

```bash:pip list
Package    Version
---------- -------
numpy      1.26.1
pip        23.3.1
setuptools 58.1.0
```

:::note alert
バージョンが指定された状態でパッケージのインストールを行わないと，望んだバージョンにはインストールされないので注意が必要です。
:::

# 3. pyenvを使用したPythonのバージョン指定解除とアンインストール

## 3.1 バージョン指定の解除

以下のコマンドを使用して，`pyenv --version`で返ってこなかったら完了です。

```bash
pyenv local --unset
```

## 3.2 アンインストール

以下のようにアンインストールを行います。
最後にバージョンが確認できなくなっていたら，完了です。

```bash
pyenv uninstall version_name
```

# 4. VS Codeにおける設定

VS Codeをエディタとして使用する場合はさらに以下の設定が推奨されます。


`settings.json`に（ユーザー，ワークスペースどちらでもよい）以下を追記します。

```json:settings.json
{
    "python.analysis.extraPaths":[
        "~/.pyenv/versions/3.9.13/lib/python3.9/site-packages"
    ]
}
```
これで、Pylanceによる「reportMissingModuleSource」に関するエラーをはかなくすることができます。




# 参考文献

[^1]: [README | pyenv](https://github.com/pyenv/pyenv/#readme)
[^2]: [Pythonのパッケージ管理ベストプラクティス](https://qiita.com/c60evaporator/items/b6a7394231d1e768ce64)
[^3]: [Troubleshooting / FAQ | pyenv](https://github.com/pyenv/pyenv/wiki#troubleshooting--faq)