【Raspberry Pi/Python】venv(仮想環境)でRPi.GPIOを使う
RPi.GPIO
モジュールと仮想環境
RPi.GPIO
を使うことができる。
仮想環境の需要と概要
輓近のpip
の使用に制限が加わった。
$ pip install TkEasyGUI
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.
If you wish to install a non-Debian-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
sure you have python3-full installed.
For more information visit http://rptl.io/venv
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
標準のpip
でのインストール、アンインストール、バージョンアップ・ダウンもまた、全てのユーザーに影響する。これを是とせず、このような告諭が憑き纏うようになったのである。
回避策は二つある。
--break-system-packages
- 仮想環境
--break-system-packages
先のメッセージを見ると、斯様な記述がある。
You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
要するに、折角の配慮に無頓着ならば、--break-system-packages
を付して強行すればよい。
pip install TkEasyGUI --break-system-packages
仮想環境
危険を冒さず、穏便に済ませたい場合には、仮想環境を作ることで対処する。
python -m venv 【命名】
例に、default_venv
という名で作るならば、次の通り。
$ python -m venv default_venv
作っただけでは意味がないため、仮想環境を有効にする。
$ source default_venv/bin/activate
仮想環境の内部にactivate
というファイルがあるため、これを指定すればよい。
$ tree -L 2
.
├── bin
│ ├── Activate.ps1
│ ├── activate
│ ├── activate.csh
│ ├── activate.fish
│ ├── pip
│ ├── pip3
│ ├── pip3.11
│ ├── python -> /usr/bin/python
│ ├── python3 -> python
│ ├── python3.11 -> python
│ ├── uv
│ └── uvx
├── include
│ └── python3.11
├── lib
│ └── python3.11
├── lib64 -> lib
└── pyvenv.cfg
7 directories, 13 files
Windowsの場合
bin
の代わりにScripts
がある。
PS C:\~中略~\.venv> tree
フォルダー パスの一覧: ボリューム OS
ボリューム シリアル番号は ~~ です
C:.
├─Lib
│ └─site-packages
│ ├─blinker
│ ├─blinker-1.8.2.dist-info
│ ├─click
│ ├─click-8.1.7.dist-info
│ ├─colorama
│ │ ├─tests
︙
│ ├─zipp-3.20.2.dist-info
│ └─__pycache__
└─Scripts
PS C:\~中略~\.venv> ls .\Scripts\
Directory: C:\~中略~\.venv\Scripts
Mode LastWriteTime Length Name
---- ------------- ------ ----
la--- 2024/10/23(水) 22:05 3798 activate
la--- 2024/10/23(水) 22:05 2386 activate_this.py
la--- 2024/10/23(水) 22:05 2346 activate.bat
la--- 2024/10/23(水) 22:05 2705 activate.csh
la--- 2024/10/23(水) 22:05 4269 activate.fish
la--- 2024/10/23(水) 22:05 3954 activate.nu
la--- 2024/10/23(水) 22:05 2782 activate.ps1
la--- 2024/10/23(水) 22:05 1728 deactivate.bat
la--- 2024/10/23(水) 22:05 43058 flask.exe
la--- 2024/10/23(水) 22:05 1215 pydoc.bat
la--- 2022/01/17(月) 15:30 597904 python.exe
la--- 2022/01/17(月) 15:30 597392 pythonw.exe
仮想環境を有効にする際は、単にactivate
を実行すればよい。
PS C:\~中略~\.venv> .\Scripts\activate
仮想環境を有効にすれば、基本的には、先のようなエラーメッセージが現れなくなる。
なお、仮想環境を脱するには、ただdeactivate
と入力する。当然乍ら、仮想環境外では、仮想環境にインストールしたものを使うことはできない。
RPi.GPIO
がない
仮想環境にdefault
の名で新たに仮想環境を作る。
$ python -m venv default
$ source default/bin/activate
(default) $ pip list
Package Version
---------- -------
pip 23.0.1
setuptools 66.1.1
上の通り、RPi.GPIO
どころか何もないため、必要に応じてインストールする。
(default) $ pip install RPi.GPIO
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting RPi.GPIO
Using cached RPi.GPIO-0.7.1.tar.gz (29 kB)
Preparing metadata (setup.py) ... done
Installing collected packages: RPi.GPIO
DEPRECATION: RPi.GPIO is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproject.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement is to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559
Running setup.py install for RPi.GPIO ... done
Successfully installed RPi.GPIO-0.7.1
インストールされたことが確認できる。
(default) $ pip list
Package Version
---------- -------
pip 23.0.1
RPi.GPIO 0.7.1
setuptools 66.1.1
(default) $ python3
Python 3.11.2 (main, May 2 2024, 11:59:08) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import RPi.GPIO
>>>
しかしRPi.GPIO
を含む種々のモジュールを標準に搭載しているため、願わくは有効に活用したいものである。このように、仮想環境外のモジュールを仮想環境内で扱う場合には、作成時に--system-site-packages
を付する。
本題
--system-site-packages
は、新たに仮想環境を作る際のオプションである。
$ python -m venv system_venv --system-site-packages
$ source system_venv/bin/activate
(system_venv) $ python3
Python 3.11.2 (main, May 2 2024, 11:59:08) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import RPi.GPIO
>>>
このように、仮想環境にインストールせずとも初めから利用できる。
仮想環境問題の発展
以上には、本題に示したものの外にも幾つか手法が見える。これらの選択に定説はなく、全く現在の用途や目的に従うものである。個人利用程度のものであれば、仮想環境を作る手間が勝ることもあろう。
しかし、少しでも本腰を入れた開発であれば、バージョンを始め、何らかの管理から遯逃することは出来ない。複数人での作業においては、バージョン等の不一致による手戻りを防ぐことが期待される。また時には、同じモジュールの異なるバージョンが同時に欲せられることもあり得る。時に枯れた技術の安定性を頼ることも、開発上有効に働く場合がある。そこで、プロジェクト毎に仮想環境を作成することで、「使うもの以外存在しない」単純明快な状態を作ることができる。
uv
モジュールと--system-site-packages
uv
は、そうした開発上の管理を簡便にするものの一つである。
(system_venv) $ pip install uv
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting uv
Downloading uv-0.4.29-py3-none-manylinux_2_28_aarch64.whl (12.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.8/12.8 MB 3.5 MB/s eta 0:00:00
Installing collected packages: uv
Successfully installed uv-0.4.29
以後、uv
というコマンドが有効になるため、pip
やpython
といったコマンドは使わなくなる。なお、これはuv
をインストールした仮想環境に限る。
プロジェクトを作る
次のコマンドで、プロジェクトの概形が作られる。
uv init 【命名】
led_blink
の名で作成する。
(system_venv) $ uv init led_blink
Initialized project `led-blink` at `/home/〜中略〜/led_blink`
(system_venv) $ tree led_blink/
led_blink/
├── README.md
├── hello.py
└── pyproject.toml
1 directory, 3 files
プロジェクト専用の仮想環境を作る
uv
の特徴として、仮想環境が(やたら)高速に作成される。仮想環境の作成にはしばしば時間を要することがあり、性能の高くない環境であるほどそれは顕著になる。プロジェクトを作る度に仮想環境の作成を待っていたが、それが全く無くなった。
ここでは--system-site-packages
を指定する。また名前を指定しないため、.venv
の名で作られる。
(system_venv) $ uv venv --system-site-packages
warning: `VIRTUAL_ENV=/home/〜中略〜/system_venv` does not match the project environment path `.venv` and will be ignored
Using CPython 3.11.2 interpreter at: /usr/bin/python
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
ここで警告が表示されるが、単なる注意である。
warning: `VIRTUAL_ENV=/home/〜中略〜/system_venv` does not match the project environment path `.venv` and will be ignored
今、uv
は仮想環境にしかないため、仮想環境を有効にした状態である。一方で、新たに別の仮想環境を作成し、扱おうとしている。
このため、「プログラム実行時には、現在有効の仮想環境が無視される」ことを伝えている。寧ろ、そのような動作を望んでいるため、特段気にする必要はない。
簡単な検証
何方が優先されるかは、動かしてみれば分かる。
対象をTkEasyGUI
モジュールとして検証する。
system_venv
にはインストールせず、.venv
にはインストールする。
(system_venv) $ python3
Python 3.11.2 (main, May 2 2024, 11:59:08) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import TkEasyGUI
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'TkEasyGUI'
>>>
.venv
は、uv
で作成したプロジェクトに紐づいている。このため、インストールは次の法が容易に済む。
(system_venv) $ uv add TkEasyGUI
warning: `VIRTUAL_ENV=/home/〜中略〜/system_venv` does not match the project environment path `.venv` and will be ignored
Resolved 4 packages in 4.22s
Built pyperclip==1.9.0
Prepared 3 packages in 3.68s
Installed 3 packages in 13ms
+ pillow==11.0.0
+ pyperclip==1.9.0
+ tkeasygui==0.2.76
プロジェクトとしてプログラムを実行する時、望むのは.venv
での動作である。従って、TkEasyGUI
が利用できることを確認すればよい。
import TkEasyGUI as tk
print(tk.__version__)
プログラムの実行は次のように記述する。
(system_venv) $ uv run import_tk.py
warning: `VIRTUAL_ENV=/home/〜中略〜/system_venv` does not match the project environment path `.venv` and will be ignored
0.2.76
TkEasyGUI
のバージョンが表示されたため、望む通り、.venv
で動作していることが確かめられた。
動作
import RPi.GPIO as GPIO
import time
LED_PORT = 17
def setup():
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PORT, GPIO.OUT)
def loop():
while True:
GPIO.output(LED_PORT, GPIO.HIGH)
time.sleep(1)
GPIO.output(LED_PORT, GPIO.LOW)
time.sleep(1)
if __name__ == '__main__':
try:
setup()
loop()
except KeyboardInterrupt:
GPIO.cleanup()
print('\r', end='')
finally:
exit(0)
配線図
回路図
跋
そもそもuv
は、Rust
で作られたものだと言う。仮想環境作成の速さはこれに起因するほか、プロジェクト単位の管理・開発手法は、Rust
に於けるcargo
によるものと酷似する。これらは煩雑と見えるも親切であり、反対に旧来の手法は簡単と見えるも不親切であったと感ずる。
Discussion