質問: MacでPythonプログラムを決められた時間に実行したいです。 普段pythonプログラムはanacondaの仮想環境内で動作させており、手順としては ``` sorce activate 仮想環境名 python 実行したい.py ``` cronを使用する下記の記事を見つけたのですが、 anacondaの指定の環境でcronを実行したい - teratail 仮想環境内で使用するPythonコマンドの場所を指定して実行すれば良いと書いてあるのですがこの場合は、`source activate`を使用して仮想環境内に入らなくても良いのでしょうか?仮想環境内のpipでモジュールを色々インストールしてあります。 **上記の理解に繋がる質問** `source activate`何をしているのか分からないため上記の質問になったため、もし実行しなくて良い場合、なぜしなくて良いのか教えて頂けると助かります。 よろしくお願いします。
回答: > > 仮想環境内で使用するPythonコマンドの場所を指定して実行すれば良いと書いてあるのですがこの場合は、source activateを使用して仮想環境内に入らなくても良いのでしょうか? > > > はい。そうです。 質問に貼ってあるURLのページにもそのように書いてあると思います。 「仮想環境に入らずにモジュールが使えるのはなぜか」というのは問い立てが逆なのです。 「元のPythonとは別のディレクトリを**サイト固有パス**として使うような、Python実行ファイルを用意すること」が仮想環境の一番大事な点です。 そして「"元のPythonとは別のディレクトリをサイト固有パスとして使うPythonコマンド"が優先して実行されるようにすること」を「仮想環境内に入る」と呼んでいると思えばいいかと思います。 その優先度の変更が`source activate`であり、そういった必要なディレクトリ/ファイルを作ることが「仮想環境が作る」ということです。 「元のPythonとは別のディレクトリをサイト固有パスとして使うような、Python実行ファイルを用意した」のですから、「仮想環境内に入らなくてもPythonコマンドを実行することで仮想環境にインストールしたモジュールが使用できる」のは、いわば当り前のことです。 **そのような実行ファイルを用意した**のですから。 > > このモジュールは初期化中に自動的にインポートされます。 > > (略) > > このモジュールをインポートすると、 -S オプションを使わない限り、サイト固有のパスをモジュール検索パスに追加し、いくつかの組み込み関数を追加します。 > > (略) > > site.main() 関数の処理は、前部と後部からなる最大で四つまでのディレクトリを構築するところから始まります。 前部では sys.prefix と sys.exec_prefix を使用します; 空の前部は使われません。 後部では、1つ目は空文字列を使い、2つ目は lib/site-packages (Windows) または lib/pythonX.Y/site-packages (Unix と Macintosh) を使います。 > > > > > モジュール検索パスに標準のサイト固有ディレクトリを追加します。 > > > とあります。 Python実行ファイルを実行すると、siteパッケージがロードされて「"Python実行ファイルのディレクトリ"の一つ上の lib/pythonX.Y/site-packages」が"サイト固有ディレクトリ"としてライブラリの探索パスに追加されます。 pipの実行ファイルもその正体はPythonスクリプトです。「pipスクリプトを動かしているPythonの実行ファイル」にしたがってライブラリをインストールします。 仮想環境のディレクトリ内に置いてあるPythonコマンドは、そのディレクトリにしたがったsite-packagesをサイト固有ディレクトリとして利用するようになっています。 つまり仮想環境`/Users/foo-user/anaconda/envs/foo-env`があったとして、 そこには`/Users/foo-user/anaconda/envs/foo-env/bin/python`があってそれを実行すると、 `/Users/foo-user/anaconda/envs/foo-env/lib/pythonX.Y/site-packages`のモジュールが利用できるようになっているのです。 その事実が「仮想環境とはなにか?」の本質です。 ``` /Users/foo-user/anaconda/envs/foo-env/bin/python -c 'import sys; print(sys.prefix); print(sys.exec_prefix)' ``` とすると自分で確かめられます。 補足 いくつかの点で話を簡単にしています。 例えば、 pyenv/pipenv/condaなどは、もう少し別の仕組みが関わっています。 dist-packagesの存在について何も言っていません。 などです。