Pythonの初学者だけど環境だけはちゃんと作りたい

# 目的
最近Pythonに興味があるので環境構築をしたい
とはいえPythonの環境ってバージョン毎の互換性やらパッケージやらが複雑なイメージ
できる限りシンプルで綺麗な環境作るにはどうしたら良いかを学びつつ自分なりの答えをメモ書き

# 目標
やりたいことは「バージョン管理」と「パッケージ管理」

本記事での「バージョン管理」はPython自体のバージョン管理のこと
「パッケージ管理」はpipで入れるライブラリを指します
(そういう呼び方が正しいかはわかりませんが)

# 実施環境
CPU: Apple M1 Pro
OS: 13.3.1 (a) 
shell: fish

Brew導入済み
https://brew.sh/index_ja

Pythonは`python3.11`っていうコマンドが叩ける状態



# 環境構築
使うのは `venv`と`pyenv`だけにした
Anacondaとかいうのがあるらしいけど、pipと競合するとかライブラリが少ないとかややこしいので使わない

## venv
パッケージ管理ができるやつ

以下の記事を参考にしました

https://qiita.com/toast-uz/items/f2df428f75b049b1d172

venvにした理由は
- 公式推奨機能
- Python導入後にさらに追加ライブラリを入れずに実行できるので特に導入作業は無し
- 簡単に環境を作れる
    - 使い方は後述


## pyenv
バージョン管理ができるやつ

本当はBrewで入れられるPythonのみで済む方がシンプルですが、使いたいライブラリによっては古いバージョンも必要になったので導入

ちなみにBrewではマイナーバージョンまでは指定できるが、パッチバージョン指定はできず最新のパッチがインストールされる
※ `3.11.1`だと3がメジャー、11がマイナー、1がパッチバージョン
(詳しくはセマンティックバージョニングで検索)

https://github.com/pyenv/pyenv

公式のREADMEを参考にインストール
```
$ brew update
$ brew install pyenv
```

自分はfish shellで作業しているため、インストール後に以下のコマンドを実行
```
$ set -Ux PYENV_ROOT $HOME/.pyenv
$ fish_add_path $PYENV_ROOT/bin
```


その後　`~/.config/fish/config.fish` に以下を追記
```
pyenv init - | source
```

### つまづいたところ
configファイルは汚したくなかったし、`| source`の意味もわかっていなかたので勝手にアレンジして以下のコマンドをshellで実施
しかしエラーが発生
```
$ pyenv init

Add pyenv executable to PATH by running
# the following interactively:

set -Ux PYENV_ROOT $HOME/.pyenv
set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths

# Load pyenv automatically by appending
# the following to ~/.config/fish/config.fish:

pyenv init - | source


# Restart your shell for the changes to take effect.

```
さらに焦ってconfigに`pyenv init`を追加したら、エンター押すだけでエラーが出るようになった

### 理由
`pyenv init`と`pyenv init -`は全然違う結果になる
  - `pyenv init` はヘルプメッセージを出す役割だった
  - `pyenv init -`は実行するpythonコマンドへのPATHを通すための設定を表示する
```
$ pyenv init - 
while set pyenv_index (contains -i -- "/Users/republicofkorokke/.pyenv/shims" $PATH)
set -eg PATH[$pyenv_index]; end; set -e pyenv_index
set -gx PATH '/Users/republicofkorokke/.pyenv/shims' $PATH
set -gx PYENV_SHELL fish
source '/opt/homebrew/Cellar/pyenv/2.3.17/libexec/../completions/pyenv.fish'
command pyenv rehash 2>/dev/null
function pyenv
  set command $argv[1]
  set -e argv[1]

  switch "$command"
  case rehash shell
    source (pyenv "sh-$command" $argv|psub)
  case '*'
    command pyenv "$command" $argv
  end
end
```
  - これを`| source`によって現在のshellに適用していた

# 使い方
準備は終わり
実質追加で導入が必要なのは`pyenv`だけだった

実際これらをどう使うかというと

Pythonを使うプロジェクトディレクトリを作成 & 移動
```
$ mkdir python_test
$ cd python_test
```

使いたいPythonバージョンを決めてpyenvでインストール
その後そのディレクトリで使うバージョンを`pyev local`で指定
(こだわりがなければBrewで入れたやつそのままでいいのでこの作業は不要)
```
$ pyenv install 3.11.0
$ pyenv local 3.11.0
```

Pythonのバージョンが指定のものになっているか、pathが`PYENV_ROOT`以下になっているかかチェック
(もしpythonコマンドが叩けない場合は`pyenv init - | source`を実行していないかも?)

```
$ which python
/Users/republicofkorokke/.pyenv/shims/python

$ python -V
Python 3.11.0
```

ライブラリ管理のためにvenv作成
その後venvを有効化
```
$ python -m venv .venv
$ source .venv/bin/activate.fish 

※venvから抜け出すには
$ deactivate
```
あとはpipで好きなライブラリ入れて遊ぶ
もしvenvを作り直したかったら `rm -rfv .venv`で削除してから作り直せばOK

## 注意
一度venvまで作ってからPythonのバージョンを変更したい場合にはvenvも作り直す必要があります
```
※venvに入ってない状態で
$ python -V
Python 3.11.0

$ pyenv local 3.10.11
$ python -V
Python 3.10.11

$ source .venv/bin/activate.fish 
$ python -V
Python 3.11.0

```
どうやらvenv自体が作成した際のpythonへのリンクを持っているようで、バージョン変更しても追従してくれません


# 〆
割と簡単にセットアップできるけど、やりたかったことは実現できました。
とりあえずこのセットで暫く遊ぼうと思います。
もし不満が出たり他にいい方法が見つかったらまた記事にするかも