Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
ModuleNotFoundErrorの傾向と対策:仕組みから学ぶImport / Unpac...
Search
Toshifumi Tsutsumi
October 27, 2023
Programming
6.8k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ModuleNotFoundErrorの傾向と対策:仕組みから学ぶImport / Unpacking ModuleNotFoundError
PyCon APAC 2023 登壇資料
https://2023-apac.pycon.jp/timetable?id=9TKP3P
Toshifumi Tsutsumi
October 27, 2023
More Decks by Toshifumi Tsutsumi
See All by Toshifumi Tsutsumi
CDCデータパイプラインを止めないために / One Stream of the CDC
tosh2230
0
1.8k
ニアリアルタイム分析の実現に向けたChange Data Captureの導入 / Change data capture for near realtime analytics
tosh2230
3
2.6k
データリネージの組織導入事例と今後の戦略 / Introduction to an example of data lineage in GMO Pepabo
tosh2230
0
1.3k
SQLクエリ解析によるE2Eデータリネージの実現 / E2E-data-lineage
tosh2230
0
4.3k
データ抽出基盤 Yeti をつくっている話 / Yeti - Yet another Extract-Transfer Infrastructure
tosh2230
1
5.7k
Loggingモジュールではじめるログ出力入門 / Introduction to Python Logging
tosh2230
33
17k
データ基盤チームの設立と直近の取り組み / the-establishment-of-pepabo-data-platform-team
tosh2230
5
4.9k
Other Decks in Programming
See All in Programming
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
950
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
240
Intent as Code
shoppingjaws
6
1.1k
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
440
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
390
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
240
スマート反転とウェブアクセシビリティ
camiha
0
210
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
120
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
270
大喜利で理解するLLM as a Judge / Understanding LLM-as-a-Judge through Ogiri
rockname
0
160
Agents on Rails - Rails at Scale 2026
irinanazarova
0
160
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
280
Featured
See All Featured
The Mindset for Success: Future Career Progression
greggifford
PRO
0
510
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Typedesign – Prime Four
hannesfritz
42
3.2k
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.1k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
530
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
2
2.9k
Bash Introduction
62gerente
615
220k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
940
Building Adaptive Systems
keathley
44
3.2k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Product Roadmaps are Hard
iamctodd
55
13k
Transcript
#pyconapac_5 ModuleNotFoundErrorの 傾向と対策 PyCon APAC 2023 2023-10-27(Day1) 仕組みから学ぶ Import
#pyconapac_5 堤 利史 Toshifumi Tsutsumi @tosh2230 Data Engineer GMO Pepabo,
inc. 風来のシレン 最新作を待ちわびています 2 自己紹介
#pyconapac_5 3 PyCon JP 2021 Loggingモジュールではじめるログ出力入門 / Introduction to Python
Logging
#pyconapac_5 4 PyCon JP 2022 SQLクエリ解析によるE2Eデータリネージの実現 / E2E-data-lineage
#pyconapac_5 このスライドは公開されています 5
#pyconapac_5 目的 🎯 6 ModuleNotFoundError の 解消にかける時間を減らすこと
#pyconapac_5 話すこと 😀 7 - ModuleNotFoundError - Import の仕組み(特に探す部分)
#pyconapac_5 話さないこと 😷 8 - Python 環境構築 - パッケージ管理ツール
#pyconapac_5 表記例 🖋 9 # これはコメント # 先頭が $ はコマンド
$ bash # 先頭が >>> は Python インタプリタ >>> import os # 先頭に何もなければ Python モジュールのコード import os
#pyconapac_5 1. Pythonのモジュールと ModuleNotFoundError 2. Importの役割 3. Importの仕組み 4. ModuleNotFoundErrorの
傾向と対策 10 Contents 📋
#pyconapac_5 1. Pythonのモジュールと ModuleNotFoundError 2. Importの役割 3. Importの仕組み 4. ModuleNotFoundErrorの
傾向と対策 11 Contents 📋
#pyconapac_5 12 ModuleNotFoundError: No module named 'foo'
#pyconapac_5 13 ModuleNotFoundError: No module named 'foo'
#pyconapac_5 14 そもそも モジュール とは?
#pyconapac_5 モジュールとは 15 - 定義や文をファイルに保存、再利用できるようにしたもの - 拡張子が .py のファイル -
Python コードの組織単位として機能する - モジュールに含まれるものの例 - 関数 - クラス - 変数
#pyconapac_5 - 複数のモジュールやサブパッケージを “ドット付きモジュール名”で構造化したもの - foo.bar は、 foo パッケージの モジュール
bar - 多くのパッケージが PyPI; Python Package Index で公開されている - パッケージには2種類ある。今回は前者を紹介 - Regular packages - Namespace packages パッケージとは 16
#pyconapac_5 Regular packages 17 - __init__.py を含む単一のディレクトリ - 読み込まれるときに __init__.py
が実行される - パッケージの初期化 - ディレクトリとパッケージが対応しているので わかりやすい
#pyconapac_5 Regular packages 18 $ tree ./greetings/friends -I __pycache__ ./greetings/friends
├── __init__.py ├── cat.py ├── dog.py └── human.py greetings friends cat dog human
#pyconapac_5 Import* 別のモジュールにある Python コードを 使えるようにすること モジュールは基本的に import して使う 19
* Import 文の解説は Python 言語リファレンス 7.11. The import statement を参照
#pyconapac_5 greetings friends # greetings.friends パッケージから # cat モジュールをインポート from
greetings.friends import cat Import の例 20 cat dog human # ./greetings/friends/cat.py class Cat: def __init__(self): self.phrase = "meow" ./greetings/friends ├── __init__.py ├── cat.py ├── dog.py └── human.py
#pyconapac_5 話は戻って ModuleNotFoundError 21 「import を試みます」 「モジュールを探しました」 「見つかりませんでした」 greetings friends
cat dog human ./greetings/friends ├── __init__.py ├── cat.py ├── dog.py └── human.py
#pyconapac_5 22 Import の 役割と仕組みが分かれば 原因を特定できるかも?
#pyconapac_5 1. Pythonのモジュールと ModuleNotFoundError 2. Importの役割 3. Importの仕組み 4. ModuleNotFoundErrorの
傾向と対策 23 Contents 📋
#pyconapac_5 Import の役割 24 > 別のモジュールにある Python コードを使えるようにすること 指定したモジュールを モジュールが存在する場所から
import を実行した名前空間へ追加する どこから 何を どこへ ✅
#pyconapac_5 Import の役割 25 > 別のモジュールにある Python コードを使えるようにすること 指定したモジュールを モジュールが存在する場所から
import を実行した 名前空間 へ追加する どこから 何を どこへ ✅ ?
#pyconapac_5 名前空間 26 - 変数や関数、クラス、モジュールの名前から オブジェクトへの対応関係を管理するもの - 各モジュールは専用の名前空間をもっているので 異なるモジュールに同じ名前の何かがあっても平気 >>>
from greetings.friends import cat >>> cat <module 'greetings.friends.cat' from '/foo/bar/greetings/friends/cat.py'>
#pyconapac_5 スコープ 27 変数や関数、クラスなどの名前が参照可能な範囲 from greetings.friends.cat import Cat global_cat =
Cat() def greet_cat_and_dog(): from greetings.friends.dog import Dog local_dog = Dog() local_cat = Cat() Global Local
#pyconapac_5 Import の役割 28 > 別のモジュールにある Python コードを使えるようにすること 指定したモジュールを モジュールが存在する場所から
import を実行した名前空間へ追加する どこから 何を どこへ ✅ ✅
#pyconapac_5 Import の役割 29 > 別のモジュールにある Python コードを使えるようにすること 指定したモジュールを モジュールが
存在する場所 から import を実行した名前空間へ追加する どこから 何を どこへ ? ✅ ✅
#pyconapac_5 1. Pythonのモジュールと ModuleNotFoundError 2. Importの役割 3. Importの仕組み 4. ModuleNotFoundErrorの
傾向と対策 30 Contents 📋
#pyconapac_5 31 同名で Import 済みの モジュールオブジェクトはあるか? 再利用 モジュールを探索 ModuleSpec はあるか?
ModuleSpec に書かれた Loader を起動 ModuleNotFoundError Import の仕組み - ModuleNotFoundError まで -
#pyconapac_5 32 同名で Import 済みの モジュールオブジェクトはあるか? 再利用 モジュールを探索 ModuleSpec はあるか?
ModuleSpec に書かれた Loader を起動 ModuleNotFoundError Import の仕組み - ModuleNotFoundError まで -
#pyconapac_5 sys.modules 33 - インポート済み モジュールオブジェクトのリスト - どの名前空間にインポートしていても再利用可能 >>> import
sys >>> sys.modules { 'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, '_frozen_importlib': <module '_frozen_importlib' (frozen)>, … }
#pyconapac_5 34 同名で Import 済みの モジュールオブジェクトはあるか? 再利用 モジュールを探索 ModuleSpec はあるか?
ModuleSpec に書かれた Loader を起動 ModuleNotFoundError Import の仕組み - ModuleNotFoundError まで -
#pyconapac_5 ModuleSpec* 35 モジュールの仕様に関する情報を扱うクラス - モジュールがある場所 - ロード方法の指定(loader) - 親モジュール・子モジュールの有無
など * PEP 451 – A ModuleSpec Type for the Import System
#pyconapac_5 1. Pythonインタプリタに組み込まれているビルトインモジュールが対象。 sys.builtin_module_names で確認可 2. フリーズされているモジュールが対象(フリーズ: Python スクリプトをバイナリフォーマット に変換して、Python
なしに直接実行できる形に変換すること) ModuleSpec の探索 sys.meta_path に設定されている Importer/Finder が探索。 主要なのは下記の3つ - BuiltinImporter1 - FlozenImporter2 - PathFinder → ModuleNotFoundError が起きやすい 36
#pyconapac_5 PathFinder 37 下記パッケージやそれに含まれる .py/.pyc* ファイルを 対象として探索 - Python にプリインストールされているパッケージ
- Python 環境にインストールしたパッケージ - 自作パッケージ * .py ファイルから生成されるバイトコードファイル 読み込みを高速化する目的で Import のタイミングで生成される
#pyconapac_5 sys.path 38 PathFinder が探しに行くディレクトリのリスト 下記の数字順に探す 1. 実行したスクリプトがあるディレクトリ (指定されなかった場合はカレントディレクトリ) 2.
PYTHONPATH 環境変数に設定されているディレクトリ 3. Python がデフォルトで検索するディレクトリ - Python のインストール方法によって異なる - site-packages ディレクトリとするのが慣例
#pyconapac_5 PathFinder で ModuleSpec を探す 39 >>> from _frozen_importlib_external import
PathFinder >>> spec = PathFinder.find_spec("greetings") # 見つからなかった場合は None が戻る >>> spec ModuleSpec( name='greetings', loader=<_frozen_importlib_external.SourceFileLoader object at 0x104eb0310>, origin='/foo/bar/greetings/__init__.py', submodule_search_locations=['/foo/bar/greetings'] )
#pyconapac_5 40 同名で Import 済みの モジュールオブジェクトはあるか? 再利用 モジュールを探索 ModuleSpec はあるか?
ModuleSpec に書かれた Loader を起動 ModuleNotFoundError Import の仕組み - ModuleNotFoundError まで -
#pyconapac_5 Import の役割 41 > 別のモジュールにある Python コードを使えるようにすること 指定したモジュールを モジュールが存在する場所から
import を実行した名前空間へ追加する どこから 何を どこへ ✅ ✅ ✅
#pyconapac_5 1. Pythonのモジュールと ModuleNotFoundError 2. Importの役割 3. Importの仕組み 4. ModuleNotFoundErrorの
傾向と対策 42 Contents 📋
#pyconapac_5 よくある原因 43 分類 原因 モジュールがない 1. 異なる仮想環境を起動している 2. パッケージのインストールを忘れている
モジュールはあるが 見つけられない 3. モジュール名を typo している 4. 同名のパッケージとモジュールがある 5. 自作パッケージが認識されていない 6. Python から見えないところにある
#pyconapac_5 分類 原因 モジュールがない 1. 異なる仮想環境を起動している 2. パッケージのインストールを忘れている モジュールはあるが 見つけられない
3. モジュール名を typo している 4. 同名のパッケージとモジュールがある 5. 自作パッケージが認識されていない 6. Python から見えないところにある よくある原因 44 実装を 見直す 環境を 見直す 起動方法を 見直す
#pyconapac_5 原因1. 異なる仮想環境を起動している 45 対策: 起動している環境が期待どおりか確認する 環境を見直す # 仮想環境のディレクトリ >>>
sys.prefix '/Users/tosh2230/Library/Caches/pypoetry/virtualenvs/unpacking -module-not-found-error-tiYZ59tI-py3.11' # 仮想環境の元となった Python のインストール先 >>> sys.base_prefix '/opt/homebrew/opt/
[email protected]
/Frameworks/Python.framework/ Versions/3.11'
#pyconapac_5 原因2. パッケージのインストールを忘れている 46 対策: パッケージの一覧を確認して、なければインストールする 環境を見直す # インストールパッケージ一覧を表示 $
pip list # カレントディレクトリから参照できるモジュールやパッケージの一覧 # モジュールを Import する前にも使える >>> help(‘modules’)
#pyconapac_5 原因3. モジュール名を typo している 47 対策: 1. IDE に誤りを指摘してもらう
2. モジュールの有無を確認する linter でチェックする - pylint - mypy など 環境を見直す 実装を見直す
#pyconapac_5 原因4. 同名のパッケージとモジュールがある 48 判別方法: 1. 標準モジュールやインストールしたパッケージと 同じ名称のモジュールはないか? → 同名の場合は自作モジュールが優先される
2. 自作パッケージと同じ名称のファイルはないか? 対策: モジュールの命名を再検討する → モジュールの役割を十分に考慮すると、名前は意外と被らない 実装を見直す
#pyconapac_5 原因5. 自作パッケージが認識されていない 49 判別方法: Import 可能なパッケージの一覧を確認する 対策: Regular package
がおすすめ。__init__.py を配置する 実装を見直す # カレントディレクトリから参照できるモジュール(パッケージ含む)の一覧 >>> help(‘modules’) # パッケージ名を指定すると、属するモジュールやサブパッケージを表示 >>> help(‘modules greetings.friends’)
#pyconapac_5 原因6. Python から見えないところにある 50 判別方法: 期待したパスが sys.path にセットされているか確認する$ python
foo/bar.py 対策: 1. PYTHONPATH 環境変数の使用を検討する 2. 設計・実装段階で起動方法を考慮に入れる → どのように起動するかで sys.path の先頭に入る値は変わる - スクリプトを起動 - モジュールをスクリプトとして起動 起動方法を 見直す >>> sys.path
#pyconapac_5 起動方法1: スクリプト 51 引数で指定したものを main モジュール* として実行する 指定可能なものは下記の3つ -
Python ファイル - __main__.py を含むディレクトリ - __main__.py を含む zip ファイル $ python foo/bar.py * __name__ に ‘__main__’ が設定されたスクリプト環境のこと。 Python 標準ライブラリ __main__ トップレベルのスクリプト環境 を参照 sys.path の先頭には 指定したファイルを含むディレクトリ がセットされる
#pyconapac_5 52 指定されたモジュールを探して、その内容を main モジュールとして実行 指定されたのがパッケージなら、そのパッケージの __main__.py を実行 sys.path の先頭には
カレントディレクトリ がセットされる # 指定するのはファイルではなく モジュール名 $ python -m foo.bar 起動方法2: モジュール* * PEP 338 – Executing modules as scripts
#pyconapac_5 Python インタプリタで import を再現してみよう 53 # ModuleSpec を探す >>>
from _frozen_importlib_external import PathFinder >>> src_spec = PathFinder.find_spec("src") >>> greetings_spec = PathFinder.find_spec("src.greetings", src_spec.submodule_search_locations, None) # モジュールをロード >>> from importlib.util import module_from_spec >>> greetings = module_from_spec(greetings_spec) >>> greetings_loader = greetings_spec.loader >>> greetings_loader.exec_module(greetings) # モジュール内の関数を実行 >>> greetings.greet_all()
#pyconapac_5 54 まとめ
#pyconapac_5 Import の役割 55 > 別のモジュールにある Python コードを使えるようにすること 指定したモジュールを モジュールが存在する場所から
import を実行した名前空間へ追加する どこから 何を どこへ ✅ ✅ ✅
#pyconapac_5 56 同名で Import 済みの モジュールオブジェクトはあるか? 再利用 モジュールを探索 ModuleSpec はあるか?
ModuleSpec に書かれた Loader を起動 ModuleNotFoundError Import の仕組み - ModuleNotFoundError まで -
#pyconapac_5 分類 原因 モジュールがない 1. 異なる仮想環境を起動している 2. パッケージのインストールを忘れている モジュールはあるが 見つけられない
3. モジュール名を typo している 4. 同名のパッケージとモジュールがある 5. 自作パッケージが認識されていない 6. Python から見えないところにある よくある原因 57 実装を 見直す 環境を 見直す 起動方法を 見直す
#pyconapac_5 ドキュメント紹介 58 Python チュートリアル 6. モジュール モジュールとパッケージの解説 Python チュートリアル
9.2. Python のスコープと名前空間 名前空間とスコープの解説 Python 標準ライブラリ importlib Approximating importlib.import_module() Import が主にやっていることを Python コードで示している Python 言語リファレンス 5. インポートシステム Import の詳細な仕様解説
#pyconapac_5 59 Thank you ! https://github.com/tosh2230/pycon-apac-2023