venv をworkon + 仮想環境名で起動できるようにする

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) venvでもcondaみたいに仮想環境を簡単に開きたい

## やること
pythonの仮想環境を開く時、

```
$ CD [仮想環境のあるディレクトリ]

# Mac
$ . [仮想環境名]/bin/activate

# Win
$ [仮想環境名]\Scripts\activate.bat
```

と、長いパスを打つ必要がありますが、これを

```
workon [仮想環境名]
```
で開けるようにします。

virtualenv用のvirtualenvwrapperがこの機能を持っていますが、python3.5から標準搭載になった公式の仮想環境であるvenv単体でこれをできるようにします。
（virtualenvwrapperはvirtualenvをインストールしないと動かないっぽいです）

## 動作環境
- mac m1 
- ログインシェル:zrc
- ターミナルで作業
　  
- Ubuntu
- ログインシェル:bash
- ターミナルで作業

**※ .zshrcや.bashrcファイルを編集するので作業は自己責任にてお願いします。**
また以下の記事はMac M1 で進めますので、Ubuntuの場合は.zshrcを.bashrcなどに読み替えてください。

## 準備

### STEP1: 仮想環境を置くディレクトリを設定する

envで仮想環境を使う時には大前提となる作業です。
もしまだ仮想環境を置くディレクトリがないという場合は新たに作ります。
仮想環境のディレクトリは下記のようにします。

```
任意のディレクトリ(Documentディレクトリなど)
　　└ 仮想環境を置くディレクトリ
　　　　　├ default(デフォルトとなる仮想環境)
　　　　　├ venv1(任意の名前の仮想環境)
　　　　　└ venv2(任意の名前の仮想環境)
```

ディレクトリはFinder上で作成してもOKですが、ターミナルで作業する場合は下記のようにします。

```shell
$ mkdir [ 仮想環境を置くディレクトリのパス ]
# 例) mkdir /Users/xxxx/Documents/pyenvs
```

### STEP2: defaultの仮想環境を作っておく

defaultとなる仮想環境を一つ作っておきます。
ディレクトリを先ほど作成した[仮想環境を置くディレクトリ]に移動し、defaultという名前の仮想環境を作ります。

```shell
$ cd [ 仮想環境を置くディレクトリのパス ]
# 例) cd /Users/xxxx/Documents/pyenvs

$ python[バージョン] -m venv default
# 例) python3.10 -m venv default
```

### STEP3: 仮想環境を置くディレクトリの絶対パスを取得する

```shell
$ pwd
# 出力例) /Users/xxxx/Documents/pyenvs
```

pwdコマンドを実行し、現在のパスを取得してコピペなどでメモしておきます。基本的には[仮想環境を置くディレクトリのパス]と同じものになるはずです。

### STEP4: 現在のシェルタイプを確認する

```shell
echo $SHELL
# 出力例) /bin/zsh
```
シェルタイプにはbashやzshなどがあります。
Macの現在のデフォルトはzshなのでその前提で進めますが、念の為zshであることを確認しておきます。


### STEP5: .zshrcを編集する
zshの設定ファイルである.zshrcを編集します。

```shell
$ cd ~/
$ ls -a #.zshrcがあることを確認
```
リストアップされるファイルの中に.zshrcがあることを確認したら、.zshrcをnanoなどのエディタで編集します。

```shell
$ sudo nano .zshrc
```

ファイルの最後に下記のコードをペーストします。

```
# 仮想環境の保存ディレクトリ（変更可能）
VENV_DIR=[ 仮想環境を置くディレクトリのパス ]　・・・①
# 例) VENV_DIR=/Users/xxxx/Documents/pyenvs       
        
# デフォルトの仮想環境名
DEFAULT_ENV=default
 
# 仮想環境のアクティベート
workon() {
    if [ -z "$1" ]; then
        # 仮想環境名が指定されていない場合、デフォルトの環境を使用
        if [ -z "$DEFAULT_ENV" ]; then
            echo "Error: No environment specified and DEFAULT_ENV is not set."
            return 1
        fi
        env_name=$DEFAULT_ENV
    else
        env_name=$1
    fi
        
    # 仮想環境が存在するか確認
    if [ -d "$VENV_DIR/$env_name" ]; then
        # 仮想環境をアクティベート
        source $VENV_DIR/$env_name/bin/activate
        echo "Activated virtual environment '$env_name'"

        # 仮想環境ディレクトリに移動
        PROJECT_DIR="$VENV_DIR/$env_name"
        if [ -d "$PROJECT_DIR" ]; then  
            cd "$PROJECT_DIR"
            echo "Changed directory to project folder: $PROJECT_DIR"
        else
            echo "No project folder found for '$env_name'."
        fi
    else  
        echo "Error: Virtual environment '$env_name' does not exist in '$VENV_DIR'."
        return 1
    fi
}

# vcdコマンドで仮想環境ディレクトリに移動
vcd() {
    if [ -d "$VENV_DIR" ]; then
        cd "$VENV_DIR"
        echo "Changed directory to $VENV_DIR"
    else
        echo "Error: Virtual environment directory '$VENV_DIR' does not exist."
        return 1
    fi
}
```
nanoの場合はctrl+xで閉じ、yで変更をセーブして終了します。
**※ターミナルウィンドウはまだ閉じないでください。.zshrcに不具合があるとターミナルを新たに開けなくなる場合がありますが、今開いているターミナルは動きます。**

### STEP6: 新しいシェルを開いてテストする
新しいターミナルウィンドウを開き、以下のコマンドを入力します。

```shell
$ workon
# 出力例) Activated virtual environment 'default'
#        Changed directory to project folder: /Users/xxxx/Documents/pyenvs/default
#        (default) xxxx@xxxx ~ % 

```
defalultで設定した環境が開きます。

workonはどのディレクトリにいても実行することができますが、実行と同時に該当の仮想環境ディレクトリに自動で移動するようにしています。

### STEP7: 基本的なコマンド

```shell
# 仮想環境の親ディレクトリにCD移動する
vcd 

#default仮想環境の開始（どのディレクトリからでも可能）
workon 

#仮想環境の開始 （どのディレクトリからでも可能）
workon [ 仮想環境名 ] #例) workon venv1

# 仮想環境の終了
deactibate 

#仮想環境を作る
python[バージョン] -m venv [ 仮想環境名 ] # 例) python3.8 -m venv py38

#仮想環境を初期状態にする
python -m venv —clear [ 仮想環境名 ]

#仮想環境を削除する
rm -rf [ 仮想環境名 ]

# 仮想環境のリストを見る
vcd
ls

# ライブラリパッケージをインストールする
pip install [ パッケージ名 ] #例）pip install numpy
```

### 超便利！だけどこれほんとにいるのか
いつものことながら、知らないだけで同じようなものがどこかにありそうな気もします。
が、なかなか見つからなかったのでメモとして置いておきます。


# 番外編 : windows版

理解100%ではありませんが、workonを導入する方法をメモしておきます。

### 前提
- powershellを使います
- pythonがインストール済みで起動できる状態

### powershellのスクリプトを作る
venv-tools.ps1というファイル名で、下記のファイルを作成します。
$VENV_DIR については、任意のディレクトリとします。

```sh:venv-tools.ps1
# 仮想環境の保存ディレクトリ（変更可能）
$VENV_DIR = "C:\Users\YourName\Documents\envs"

# デフォルトの仮想環境名
$DEFAULT_ENV = "default"

function workon {
    param (
        [string]$env_name = $DEFAULT_ENV
    )

    $env_path = Join-Path $VENV_DIR $env_name

    if (Test-Path "$env_path") {
        $activateScript = Join-Path $env_path "Scripts\Activate.ps1"

        if (Test-Path $activateScript) {
            & $activateScript
            Write-Host "Activated virtual environment '$env_name'"

            Set-Location $env_path
            Write-Host "Changed directory to project folder: $env_path"
        } else {
            Write-Host "Error: Activate script not found in '$env_path'"
        }
    } else {
        Write-Host "Error: Virtual environment '$env_name' does not exist in '$VENV_DIR'."
    }
}

function vcd {
    if (Test-Path $VENV_DIR) {
        Set-Location $VENV_DIR
        Write-Host "Changed directory to $VENV_DIR"
    } else {
        Write-Host "Error: Virtual environment directory '$VENV_DIR' does not exist."
    }
}
```
できたvenv-tools.ps1を、都合のよい適当な場所におきます。（Cドライブの第一階層に作成したディレクトリ内など）
そのファイルのパスを記録しておきます。・・・②

### $PROFILE を設定する
PowerShell起動時に自動で読み込めるように$PROFILEを設定します。
PowerShellを開いて、
```
$PROFILE
```
と入力すると、Microsoft.PowerShell_profile.ps1のパスが表示されるのでコピーします。・・・③
次に、以下のようにnotepad + [③をペースト] とします。
```
notepad C:¥Users¥[パス]¥$Microsoft.PowerShell_profile.ps1
```
エディタが開くので、
```
. "C:\Users\YourName\Documents\venv-tools.ps1"（②のパス）
```
を記入して保存します。
これで、workon + 環境名で仮想環境を開く準備ができました。

### 仮想環境を作る
パワーシェルで
```shell
vcd
```
と入力すると、①で作成したディレクトリに飛びます。
そこで仮想環境を作成します。

```shell
python -m venv default
```
とすると「default」という名前の仮想環境ができます。
（pythonのバージョン指定についてはまだうまくいっていません。）
同様の手順で、仮想環境を増やしていくことが出来ます。

```shell
workon default
```
で、仮想環境を開くことができるようになりました。
... のはずです。