はじめに
最近はすっかりプログラミングから離れている @riocampos です。とはいえ Ruby はいちおう書けるし、テキトーな自動化はできます。
最近、heroku の無料プランが終了するとの記事がありました。
とても世話になったのですが今は動かさず放置してます。なので heroku のアプリが消え去っても仕方ないでしょう。ただ、サーバで動かしたいことはいろいろあるのです。引越を検討する必要もあるのでしょう。
で。
heroku では Ruby がメインに近い言語として取り扱われていましたが、他の無料 PaaS では動かなさそう…。以前から Python も勉強しなきゃと思っていたので、そろそろ動き出そうかと。
環境構築
基本的にコレに従う事にしました。
なお現在の環境は
- MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)
- macOS Big Sur 11.6(アップデートしてない…)
前準備:pyenv を削除
個人的に言語のバージョン管理は anyenv を使っています。で、何か似たような名前の venv というのが出てきてるので何だろうと悩んでいましたが、バージョン管理ではなくパッケージ管理なのですね。
で、久しぶりに anyenv を使って pyenv を更新しようとしたのですが…
$ anyenv update -v pyenv Updating 'pyenv'... | cd /Users/riocampos/.anyenv/envs/pyenv | fatal: unable to connect to github.com: | github.com[0: 20.27.177.113]: errno=Operation timed out | | Failed to update. Use 'verbose' option for detailed, or 'force' option. Updating 'pyenv/pyenv-pip-rehash'... | cd /Users/riocampos/.anyenv/envs/pyenv/plugins/pyenv-pip-rehash | Already up to date. Skipping 'pyenv/python-build'; not git repo Updating 'anyenv manifest directory'... | cd /Users/riocampos/.config/anyenv/anyenv-install | Already up to date.
なにやらエラーが出てる。 pyenv 自体は今もアクティブなプロジェクトだし、anyenv も生きてる。
とはいえ、もう Python 2 を使う事も無いだろうし、バージョンを変えることもまず無いかなあと。それに以下のようなことも書かれてます。
複数のバージョンのPythonを同時にインストールして利用しても問題ないようになっています。
例えばPython3.7と3.8を同時にインストールしておくと、macOSやUnix環境では python3.7 コマンドと python3.8 コマンドで使用するバージョンを切り分けて実行できます。
さらには
などという記事まで…。
なので pyenv を消しちゃいます。
$ anyenv uninstall pyenv anyenv: remove /Users/riocampos/.anyenv/envs/pyenv? y $ ls -l ~/.anyenv/envs total 0 drwxr-xr-x 18 riocampos staff 576 7 25 2019 crenv drwxr-xr-x 30 riocampos staff 960 9 7 10:05 goenv drwxrwxr-x 25 riocampos staff 800 5 14 2021 nodenv lrwxr-xr-x 1 riocampos staff 19 6 10 2019 rbenv -> /Users/riocampos/.rbenv/
そして anyenv を使う前から pyenv を使っていた(移行の経緯のメモ→ anyenvをインストール2 - 別館 子子子子子子(ねこのここねこ)はてブロ部)ので、 pyenv 自体も手動で消します。
$ ls -l ~/.pyenv/ total 392 -rw-r--r-- 1 riocampos staff 35414 10 3 2021 CHANGELOG.md -rw-r--r-- 1 riocampos staff 9411 10 3 2021 COMMANDS.md -rw-r--r-- 1 riocampos staff 3380 5 14 2021 CONDUCT.md -rw-r--r-- 1 riocampos staff 680 5 14 2021 Dockerfile -rw-r--r-- 1 riocampos staff 1092 10 19 2014 LICENSE -rw-r--r-- 1 riocampos staff 852 5 14 2021 Makefile -rw-r--r-- 1 riocampos staff 22146 10 3 2021 README.md drwxr-xr-x 3 riocampos staff 96 4 13 2016 bin drwxr-xr-x 5 riocampos staff 160 2 24 2017 completions drwxr-xr-x 27 riocampos staff 864 10 3 2021 libexec drwxr-xr-x 3 riocampos staff 96 10 3 2021 man drwxr-xr-x@ 6 riocampos staff 192 10 19 2014 plugins drwxr-xr-x 5 riocampos staff 160 5 14 2021 pyenv.d drwxr-xr-x@ 34 riocampos staff 1088 9 7 10:21 shims drwxr-xr-x 7 riocampos staff 224 7 19 2018 src -rw-rw-r-- 1 riocampos staff 104764 7 19 2018 terminal_output.png drwxr-xr-x 29 riocampos staff 928 10 3 2021 test -rw-r--r--@ 1 riocampos staff 13 2 7 2018 version drwxr-xr-x@ 5 riocampos staff 160 2 7 2018 versions $ rm -rf ~/.pyenv
消えました。
Homebrew で Python をインストール
先にも書いたけど
これに従っていきます。
Homebrew で Python を入れる手順になってますね。以前から Homebrew は使ってるし、他のコマンドをインストールするときに Python が入ってるんじゃないかなあ、ってことで先ずは確認。
$ brew list | grep python python@2 python@3.10 python@3.8 python@3.9 $ which python /usr/bin/python $ which python3 /usr/local/bin/python3 $ which python3.10 /usr/local/bin/python3.10 $ python --version Python 2.7.16 $ python3 --version Python 3.10.6
既にいっぱい入ってた。んで $ python
だとシステムのほうの Python 2.7.16 が動いちゃうことも分かった。
python
コマンドを実行すると、プレインストールされた Python 2.7を実行してしまいます。間違えて実行しないように気をつけましょう。
pip
pip は、The Python Package Index に公開されているPythonパッケージのインストールなどを行うユーティリティで、Python 3.4以降には、標準で付属しています。
ってことは改めてインストールする必要無いと。
パッケージのインストールは、
pip
のinstall
コマンドで行います。例えば、Pythonの代表的な画像処理パッケージpillow
パッケージをインストールするときは、次のように実行します。$ python3 -m pip install pillow
Note
python3
コマンドを使わず、pip3
コマンドを使っても実行できますが、初心者の方にはpython3 -m pip ...
の形式をおすすめします。不要なパッケージは、
uninstall
コマンドで削除できます。つぎの例は、pillow
パッケージを削除します。$ python3 -m pip uninstall pillow
どうやら Python の複数のバージョンを入れているときには、パッケージもバージョン毎に入れることになるようですね(参考:【Python】”pip install” と “python -m pip install” の違い | だえうホームページ)。なので python3 -m pip install ...
のほうが好ましいと。
脱線:python -m ...
とは
今後はたびたび公式ドキュメントを引用していきます。
sys.path
から指定されたモジュール名のモジュールを探し、その内容を__main__
モジュールとして実行します。引数は module 名なので、拡張子 (
.py
) を含めてはいけません。モジュール名は有効な Python の絶対モジュール名 (absolute module name) であるべきですが、実装がそれを強制しているとは限りません (例えば、ハイフンを名前に含める事を許可するかもしれません)。パッケージ名 (名前空間パッケージも含む) でも構いません。通常のモジュールの代わりにパッケージ名が与えられた場合、インタプリタは
<pkg>.__main__
をmain
モジュールとして実行します。この挙動はスクリプト引数として渡されたディレクトリや zip ファイルをインタプリタが処理するのと意図的に同じにしています。このオプションが指定された場合、
sys.argv
の最初の要素はモジュールファイルのフルパスになります (モジュールファイルを検索している間、最初の要素は"-m"
に設定されます)。-c
オプションと同様に、カレントディレクトリがsys.path
の先頭に追加されます。
正直なところ、この段落の半分も分からない。が、これらのドキュメントを読めるようになることが学習目的でもあるので頑張る。
現状で分かるのは、pip ユーティリティもモジュールであり、単体実行(pip install ...
)できるけど、Python インタプリタから実行する(python3 -m pip install ...
)こともできる、ということ。そして後者だと、どのバージョンの Python を使って pip を実行するか、すなわちどのバージョンの Python にパッケージをインストールするのかを明示して作業できる、ってこと。
いまのところは Python 3.10 しか使わないので問題ないけど、パッケージも Python のバージョン依存があるようだし、不確定要因があるとデバッグも面倒になるので python3 -m pip install ...
で pip を使うように癖付けておきたい。
venv
とうとう来たね venv 。
sample.py
import requests print(requests.get("https://www.python.jp").text)
で。これだと requests モジュール*1が入ってないよ、ってエラーが出るんだけど、リンク先だと
ImportError: No module named requests
とある。でも Python 3.10 だと
ModuleNotFoundError: No module named 'requests'
になってる。調べると3.6から変わったようだ。
exception
ModuleNotFoundError
ImportError
のサブクラスで、import
文でモジュールが見つからない場合に送出されます。また、sys.modules
にNone
が含まれる場合にも送出されます。バージョン 3.6 で追加.
続いて仮想環境を作る。.venv ディレクトリ以下に仮想環境のモジュールなどをぶち込むようですな。公式でも .venv が「よく使われるディレクトリ名」だと書いてます。
$ python3 -m venv .venv $ ls -l total 8 -rw-r--r--@ 1 riocampos staff 65 9 7 11:37 sample.py $ ls -al total 8 drwxr-xr-x 4 riocampos staff 128 9 7 11:49 . drwxrwxr-x@ 5 riocampos staff 160 9 7 11:36 .. drwxr-xr-x 6 riocampos staff 192 9 7 11:49 .venv -rw-r--r--@ 1 riocampos staff 65 9 7 11:37 sample.py $ ls -al .venv/ total 8 drwxr-xr-x 6 riocampos staff 192 9 7 11:49 . drwxr-xr-x 4 riocampos staff 128 9 7 11:49 .. drwxr-xr-x 12 riocampos staff 384 9 7 11:49 bin drwxr-xr-x 2 riocampos staff 64 9 7 11:49 include drwxr-xr-x 3 riocampos staff 96 9 7 11:49 lib -rw-r--r-- 1 riocampos staff 92 9 7 11:49 pyvenv.cfg
あっという間にファイルがたくさん作られた。
続いて仮想環境をアクティブにする*2と、プロンプト($
)の前に仮想環境のディレクトリ名が追加される。
$ source .venv/bin/activate (.venv) $
仮想環境下で requests モジュールのインストールを実行。上記したように python3 -m pip install ...
の手法で。
(.venv) $ python3 -m pip install requests Collecting requests Downloading requests-2.28.1-py3-none-any.whl (62 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 62.8/62.8 kB 669.4 kB/s eta 0:00:00 Collecting certifi>=2017.4.17 Downloading certifi-2022.6.15-py3-none-any.whl (160 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 160.2/160.2 kB 1.2 MB/s eta 0:00:00 Collecting idna<4,>=2.5 Downloading idna-3.3-py3-none-any.whl (61 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 61.2/61.2 kB 1.6 MB/s eta 0:00:00 Collecting charset-normalizer<3,>=2 Downloading charset_normalizer-2.1.1-py3-none-any.whl (39 kB) Collecting urllib3<1.27,>=1.21.1 Downloading urllib3-1.26.12-py2.py3-none-any.whl (140 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 140.4/140.4 kB 1.4 MB/s eta 0:00:00 Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests Successfully installed certifi-2022.6.15 charset-normalizer-2.1.1 idna-3.3 requests-2.28.1 urllib3-1.26.12
sample1/.venv/lib/python3.10/site-packages 以下に5つのモジュールがインストールされた。
ちなみにこの時点で sample1 ディレクトリの容量は 20.3MB(requests モジュールのインストール前の sample1 ディレクトリの容量は 18.2MB。そのうち pip が 11.6MB、setuptools が 4.8MB、その他が1.8MB。requests モジュールのインストールで 2MB ほど追加されたわけか)。仮想環境を1つ作ると、わりと容量喰いますね。
では再度スクリプト実行。
(.venv) $ python3 sample.py <!DOCTYPE html> <html lang="ja"> <head> : </body> </html>
https://www.python.jp からの HTML のダウンロードに成功。
仮想環境から抜け出すには deactivate
。通常のプロンプトに戻る。
(.venv) $ deactivate $
仮想環境から抜け出すコマンドは簡単なのに、仮想環境に入るときのコマンドは何だか面倒に感じる。
ということで環境構築は出来た。あとは「Python[完全]入門」オススメのVisual Studio Code – コード エディター | Microsoft Azureをインストールしておこう。
とりあえずここまでで区切り。
良さげだと感じた本たち(まだ買ってない
無料 Python 入門書
*1:Ruby の癖で「requests ライブラリ」とか書いてしまいそう→どうやら「ライブラリ」の中に「モジュール」と「パッケージ」が含まれるらしい→Python のコーディング規約 PEP 8 ってなに? | 民主主義に乾杯
*2:もちろん '. .venv/bin/activate' のほうが短くて楽ではあるのだけど、'.' だと何なのか分からないので好きじゃない。ので 'source' と明記。