🐍

新MacでLinux:Kubuntu24.04 Dev Python ①pyenv

2024/12/26に公開

今回の内容

Apple Silicone MacにKubuntuを入れるシリーズ、今日はpythonの環境の入れ方について解説します。Pythonは人気のあるプログラミング言語ですが、勿論Linuxでも動きますも。ただしこれからPythonを学ぶのであれば、MacOSに直接入れたほうが良いです。仮想マシンで動かすよりスピードが速いですし、MacOSはUNIXなので使い勝手は同じですからね。しかしLinuxで使いたいときもあるでしょう。そこで今回はこのシリーズで入れたKubuntu LinuxにPythonをインストールする方法について書きます。

sudo apt install python 

お疲れ様でした!・・・冗談です。いえ、これでも良いのですよ。
しかし折角ですからもう少し便利に使える方法を書こうと思います。

Ubuntuには最初からPythonが入っています

そう、インストールしなくても最初から入っています。MacOSにも入っています。
ただしどの様に入っているかはLinuxの種類(ディストリビューション)によって違います。
そして最初から入っているpythonは「システムが、そのpythonが必ず有ることを前提にしている」場合があります。ですから私個人の感覚としてなるべく触りたくない。自分のプログラミングには使いません。好きに触るpythonを自分で入れればバージョンアップでもなんでも恐れる必要がありません。
また今回入れるpyenvでは、最初から入っているシステムpythonと共存して切り替えることも出来ますので安心です。

Pythonの管理方法はたくさんあります

Pythonは色々な配布形態があります。この記事は初めてLinuxを始めた人向けですから、まず何故多くの配布形態があるのか少し書きます。

  • Python自体のバージョン管理
    Pythonは日々開発が継続しており、多くのバージョンがあります。新しいものが過去と完全にご完成を持つなら良いのですが、Pyhtonはバージョン事に大きな変更を伴う場合が多く互換性がない機能もあり、バージョン毎に各種ライブラリと相性があります。例えばあるライブラリは特定のバージョンじゃないと使えない事があります。そこでPythonは複数のバージョンを切り替えられたほうが便利なのですが、この管理方法にも色々あります。
  • ライブラリ管理
    Pythonの人気が出た理由の一つは”豊富なライブラリがある”ことです。ライブラリというのは便利な部品集ですね。最初Pythonが出た頃はライブラリの扱いが結構難しかったので、それを便利に使いたいと独自の管理方法や簡単なインストールの仕組みを考えた人たちがいました。この管理方法が幾つか種類があるんです。
  • 仮想環境の管理
    仮想環境というのはLinuxを入れた仮想マシンではなく、Pythonの仮想環境のことです。上記の通りPythonは色々とバージョンについて考える必要があります。これは実際にプログラムを作ることを考えると、「プログラムAではこのライブラリ、Pythonはこのバージョン。プログラムBはPythonはこのバージョンだけどライブラリはこのバージョン、さらに設定はこうで・・」と頭が痛い問題です。そこで考えられたのが、「プログラム事にディレクトリを作り、必要なバージョンのPythonとライブラリファイルを纏める」方法です。プログラムごとに、Pythonやライブラリのバージョンを切り替える仕組み。これをPythonの仮想環境といいます。

この管理方法の違い、主に扱うライブラリの違い。この問題を解決するために色々な管理方法が作られ配布されました。これがPythonの配布形態の種類が色々ある理由です。もし新しいPython管理の話題が出たときは、この3つのどの話なのか気をつければ理解しやすいと思います。

さて、今回はまずシンプルに複数のバージョンのPythonを入れる方法についてです。これはMacOSでも同じことができます。pyenvという仕組みを入れていきます。

pyenvとは

pyenvというのは上記のなかで「複数のバージョンのPythonをインストール、管理するための仕組み」です。簡単に切り替えて使うことができるので便利です。この様な何かしらの仕組みを使わないとPythonは一つのバージョンしか使えません。

pyenvの仕組みは簡単にいうと

  • ホームディレクトリに.pyenvというディレクトリを作る
  • .pyenvの下にversionsというディレクトリを作り、バージョン事に分けてpythonをインストールする
  • 現在の設定によってどのバージョンのpythonを呼び出すか切り替える
    という構造になっています。

つまり、この.pyenvディレクトリを消せば綺麗サッパリ消えますから安心して入れてください。

インストール

まずはこちらがpyenvのサイトです(githubについて知らなくても大丈夫)
linuxのインストールの部分に飛びます。
https://github.com/pyenv/pyenv?tab=readme-ov-file#linuxunix



この部分に書いてある、automatic installerを使っていれましょう。下記の部分をコピーして、ターミナルに貼り付けます。この連載通りKubuntuならKonsoleです。

curl https://pyenv.run | bash

すると、自動的にインストールが始まります。

大事なのでメッセージを見てみましょう。

pyenv installer
armlin@arm-vm:~$ curl https://pyenv.run | bash
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   270  100   270    0     0    353      0 --:--:-- --:--:-- --:--:--   353
Cloning into '/home/armlin/.pyenv'...
remote: Enumerating objects: 1304, done.
remote: Counting objects: 100% (1304/1304), done.
remote: Compressing objects: 100% (721/721), done.
remote: Total 1304 (delta 769), reused 757 (delta 450), pack-reused 0 (from 0)
Receiving objects: 100% (1304/1304), 1.12 MiB | 4.78 MiB/s, done.
Resolving deltas: 100% (769/769), done.
Cloning into '/home/armlin/.pyenv/plugins/pyenv-doctor'...
remote: Enumerating objects: 11, done.
remote: Counting objects: 100% (11/11), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 11 (delta 1), reused 5 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (11/11), 38.72 KiB | 1.55 MiB/s, done.
Resolving deltas: 100% (1/1), done.
Cloning into '/home/armlin/.pyenv/plugins/pyenv-update'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 10 (delta 1), reused 5 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (10/10), done.
Resolving deltas: 100% (1/1), done.
Cloning into '/home/armlin/.pyenv/plugins/pyenv-virtualenv'...
remote: Enumerating objects: 64, done.
remote: Counting objects: 100% (64/64), done.
remote: Compressing objects: 100% (57/57), done.
remote: Total 64 (delta 10), reused 23 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (64/64), 43.06 KiB | 2.87 MiB/s, done.
Resolving deltas: 100% (10/10), done.

WARNING: seems you still have not added 'pyenv' to the load path.

# Load pyenv automatically by appending
# the following to 
# ~/.bash_profile if it exists, otherwise ~/.profile (for login shells)
# and ~/.bashrc (for interactive shells) :

export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

# Restart your shell for the changes to take effect.

# Load pyenv-virtualenv automatically by adding
# the following to ~/.bashrc:

eval "$(pyenv virtualenv-init -)"

ここで前半は何やらダウンロードして、ホームディレクトリの.pyenvに書き込んでいます。注目は最後です。

WARNINGとあり、その後に追加の設定が必要だと書いてあります。これをあなたの.bash_profile.profile .bashrcに書きなさいと出ています。
その後のものはオプションですからひとまず初めてなら無視で大丈夫です。

Path設定警告
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

エディタで上記のファイルのどれかにコピペしましょう。KubuntuならばKateを使うのが簡単です。どのファイルにすればよいか判断できない場合には.profileをお勧めします。サイトには複数のファイルに書くように解説されていますが、起動速度が遅くなるだけなのでこれで十分です。


ファイルを開くとき、.から始まるファイル名は隠しファイルで見えません。ここでCtrl+hを同時に押すと見えるようになります。または右上のギアアイコンを押すと隠しファイルを表示するメニューもあります。

では最後にコピペします

保存したら、一度ログアウトして再度ログインしてください。

もう一度ターミナルを開いてpyenvと打って見ましょう。起動すれば成功です。

もう少し便利に設定する

これで使うことはできるのですが、サイトには便利にする方法が書いてあります。


以前この連載で書きましたが、bashもzshもメジャーなシェルはコマンドの補完が効きます。例えばコマンドを入れてからtabキーを押すと、オプションが選択肢として表示されます。これがpyenvでも出来るように設定しましょう。

下記を.bashrcに追記します。(bashなら必ずこのファイルです。zshなら.zshrc)

補完設定(bashの場合)
source $(pyenv root)/completions/pyenv.bash

もしzshなら最後をzshにしましょう。fishもあります。

これでpyenvと売ってTabを押すと下の図のように候補が出てきます。コマンドを選んでTabを押すと更に詳細オプションが出ます。試してみてください。

Pythonを入れる準備

今どのバージョンが入っているか見るためには、このコマンドです。(最後のsを忘れずに)

pyenv versions

system としか出ませんね?これは最初からubuntuに入っているものだけという意味です。

これから複数バージョンのpythonを入れますが、ここで大事なことが。

実はpyenvでpythonをインストールする時、pyenvはpythonを1からコンパイルします
(念の為コンパイルというのは、プログラムとしてpython自身を作ることです。)

ですから、C言語で書かれているPythonをコンパイルするツールが必要になります。サイトに書いてあります。
https://github.com/pyenv/pyenv/wiki#suggested-build-environment

ここにUbuntuで必要なものが書いてありますから、素直にコピーしてターミナルで実行します。

pythonコンパイル依存ファイル
sudo apt update; sudo apt install build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl git \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev

これで大丈夫です。

Pythonのインストール

では早速Pythonを入れましょう。下記のコマンドを実行すると一覧が出てきます。

インストール出来るPythonの一覧
pyenv install -l

沢山出てきますね。この中で、anacondaやpypyなど名前から始まるものは最初に説明した配布形態の一つです。pyenvはこれらも入れることができます。しかしpyenvで入れるのはおすすめしません。メリットがあまりないんです。(anacondaについては入れ方を今後の記事で紹介する予定です)
3.10など数字から始まるものが、純粋なPythonです。

どのバージョンを入れるかは好みですが、3.10.xx 3.12.xxなど最初の2つの数字が大きく変化する区切り、最後の数字は小さい修正と思ってください。大きなバージョンはかなり変更が加えられます。

pyenvはこのメジャーバージョンを入れ替える仕組みですから、お勧めは複数のメジャーバージョンを常に最新のマイナーバージョンで追いかけることです。ですからここは

3.10.xx
3.11.xx
3.12.xx
3.13.xx
と幾つか入れてみましょう。いつでも消すことはできますし共存できます(そのためのpyenvです)。
次のように入れると、そのメジャーバージョンの最新版が入ります。マイナーバージョンまで指定することもできます。

pyenv install -v 3.10

するとpyenvはPythonのソースファイル(プログラム)をダウンロードし、コンパイルを始めます。多少時間がかかります。-vをつけると動作を詳細に表示します。最初はつけて動きを見てみると良いです。幾つかのバージョンを入れてみてください。

終わったら入ったものを見てみましょう。

pyenv versions


一覧に並んでいますね。これで成功です。

バージョン切り替えの仕方

まず今はsystemが選ばれています。今入れたものに切り替えてみましょう。

バージョン切り替え
pyenv global 3.12

するとシステム全体で使うPythonのバージョンが切り替わります。

バージョン確認
armlin@arm-vm:~$ python -V
Python 3.12.8

いつでも切り替える事ができます。マイナーバージョンまで指定することももちろん出来ます。
もう一つの切り替え方はこうです。

pyenv local 3.11

こうすると 今いるディレクトリで使うバージョンだけが変わります
つまり、作っているプログラム毎に自動で切り替えることが出来ます。localで指定すると、その指定をしたディレクトリ内では指定したバージョンが起動します。

armlin@arm-vm:~$ mkdir tesA tesB
armlin@arm-vm:~$ cd tesA
armlin@arm-vm:~/tesA$ pyenv local 3.12
armlin@arm-vm:~/tesA$ python -V
Python 3.12.8
armlin@arm-vm:~/tesA$ cd ../tesB
armlin@arm-vm:~/tesB$ pyenv local 3.11
armlin@arm-vm:~/tesB$ python -V
Python 3.11.11

またlocalの指定を取り消す場合にはこうします。するとシステム全体の設定が有効になります。

pyenv local --unset

pyenvの仕組みをもう少し知っておく

pyenvは最初に説明した通り、各バージョンのPythonを~/.pyenvに格納します。

cd ~/.pyenv
ls

この中身を見ます。treeコマンドはこういう時に便利です。無ければ入れておきましょう。

sudo apt install tree

そしてこの様に使います。-Lは幾つまでディレクトリを掘り下げるかです。今回は出力を少し削って記載します。

armlin@arm-vm:~$ tree -L 2 ~/.pyenv
/home/armlin/.pyenv
├── bin
│   └── pyenv -> ../libexec/pyenv
├── CHANGELOG.md
├── COMMANDS.md
├── completions
├── CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── install_local_python.gif
├── libexec
│   ├── pyenv
│   ├── pyenv-commands
│   ├── pyenv-completions
│   ├── pyenv-exec
│   ├── pyenv-global
│   ├── pyenv-help
│   ├── pyenv-hooks
│   ├── pyenv-init
│   ├── pyenv-latest
│   ├── pyenv-local
│   ├── pyenv-prefix
│   ├── pyenv-rehash
│   ├── pyenv-root
│   ├── pyenv-shims
│   ├── pyenv-sh-rehash
│   ├── pyenv-sh-shell
│   ├── pyenv---version
│   ├── pyenv-version
│   ├── pyenv-version-file
│   ├── pyenv-version-file-read
│   ├── pyenv-version-file-write
│   ├── pyenv-version-name
│   ├── pyenv-version-origin
│   ├── pyenv-versions
│   ├── pyenv-whence
│   └── pyenv-which
├── LICENSE
├── MAINTENANCE.md
├── Makefile
├── man
├── plugins
├── pyenv.d
├── README.md
├── shims
│   ├── 2to3
│   ├── 2to3-3.10
│   ├── 2to3-3.11
│   ├── 2to3-3.12
│   ├── idle
│   ├── idle3
│   ├── idle3.10
│   ├── idle3.11
│   ├── idle3.12
│   ├── idle3.13
│   ├── pip
│   ├── pip3
│   ├── pip3.10
│   ├── pip3.11
│   ├── pip3.12
│   ├── pip3.13
│   ├── pydoc
│   ├── pydoc3
│   ├── pydoc3.10
│   ├── pydoc3.11
│   ├── pydoc3.12
│   ├── pydoc3.13
│   ├── python
│   ├── python3
│   ├── python3.10
│   ├── python3.10-config
│   ├── python3.10-gdb.py
│   ├── python3.11
│   ├── python3.11-config
│   ├── python3.11-gdb.py
│   ├── python3.12
│   ├── python3.12-config
│   ├── python3.12-gdb.py
│   ├── python3.13
│   ├── python3.13-config
│   ├── python3.13-gdb.py
│   ├── python3.13t
│   ├── python3.13t-config
│   ├── python3-config
│   └── python-config
├── src
├── terminal_output.png
├── test
├── version
└── versions
    ├── 3.10.16
    ├── 3.11.11
    ├── 3.12.8
    ├── 3.13.1
    └── 3.13.1t

25 directories, 114 files
  • pyenv自体はlibexecディレクトリにあります。binにあるのは本物へのリンク(MacOSで言うエイリアス)です。
  • versionsの中にあるバージョン番号のディレクトリの下に、各バージョンの沢山のファイルがあります。
  • shimsの中にあるのは、バージョンを切り替えて実行する、"本当のコマンドと同じ名前のスクリプト"です。コマンドを実行すると、Pathの設定によりこれが呼び出される様になっています。

ちょっと覗いてみましょう。

.pyenv/shims/python
#!/usr/bin/env bash
set -e
[ -n "$PYENV_DEBUG" ] && set -x

program="${0##*/}"

export PYENV_ROOT="/home/armlin/.pyenv"
exec "/home/armlin/.pyenv/libexec/pyenv" exec "$program" "$@"

細かい説明は抜きにして、pyenvを使うとpython を実行するとこの.pyenv/shims/pythonが呼び出されて、その内部では下記のコマンドが実行されるようになっています。

pyenv exec python 引数

そしてpyenvはexec+コマンド名オプション付きで実行すると、今設定されているバージョンのそのコマンドを探して実行します。

ライブラリの場所

pyenvを使う時、ライブラリがどこに保存されるか知っておくと良いです。
tree-dオプションはディレクトリのみを表示します。

armlin@arm-vm:~$ tree -dL 2 ~/.pyenv/versions/3.11.11/
/home/armlin/.pyenv/versions/3.11.11/
├── bin
├── include
│   └── python3.11
├── lib
│   ├── pkgconfig
│   └── python3.11
└── share
    └── man

9 directories

このlib/python3.11の中にsite-packagesというディレクトリがあり、そこに保管されます。これは各バージョンごとに一つです。つまり、PythonのライブラリはPythonバージョンごとに1セットということですね。pipというコマンドで入れるのですが、その保管先はここだと知っておくといつか役に立ちますよ。

まとめ

以上でpyenvの設定が完了です。実は今回の説明はある意図があって長々と書きました。
ネットや本でPythonを勉強するとき、大抵Pythonのインストーラで一つのバージョンを入れる説明になっています。それでも良いのですが、上で書いたようにいつかPythonやライブラリの違うバージョンを使いたい時に困ったりするんです。そこで、ここから先他の文献を見ても違和感なく今日紹介したpyenvが使えるよう、構造や仕組みを説明しました。

これでpythonの勉強を始められますよ!その本が3.12を対象にしていたら3.12に切り替えれば良いのです。別の本が3.10を使っていたら3.10に。便利ですね。

でも最初に3つ、管理の仕組みを書きましたね?
pythonバージョン管理
仮想環境
ライブラリの管理

次回は仮想環境とライブラリの管理を行う方法の一つとして、poetryを紹介します。
では今回はここまでです。また次回の記事で会いましょう!

Discussion