0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

もう__init__.pyはいらない?Python 3.3で変わったパッケージの仕組み

0
Last updated at Posted at 2025-10-05

きっかけ

サブパッケージからimportする際に、パッケージとして認識させるために__init__.pyが必要だと思っていたがチーム内のレビューで可能であれば削除してほしいとコメントをもらったことをキッカケに深堀しました。

Python 3.3以降

Python 3.3 (2012年):PEP 420: implicit Namespace Packages(暗黙の名前空間パッケージ)
 → 明示的に__init__.pyでパッケージ定義しなくても自動的にサブパッケージを探索してくれるようになった

2025年10月時点では、Python 3.13が最新バージョンなのでほとんどのケースがこのPython3.3以降のケースにあたると思われます。

Python 2.3 ~ 3.2

Python 2.3 (2003年):標準ライブラリpkgutilモジュールのpkgutil.extend_path()関数で名前空間パッケージを拡張
 → サブパッケージに以下のような__init__.pyを使うことで名前空間パッケージを拡張していた

__path__ = __import__('pkgutil').extend_path(__path__, __name__)

この方法はPython 2.3 ~ Python 3.2までのバージョン互換性に対応したい場合に今でも使われるようでした。
参考:名前空間パッケージをパッケージする - Python Packaging User Guide

Python 2.2以前

Python 2.2以前:外部ライブラリであるsetuptoolspkg_resources.declare_namespace関数で名前空間パッケージを拡張
 → サブパッケージに以下のような__init__.pyを使うことで名前空間パッケージを拡張していた

__import__('pkg_resources').declare_namespace(__name__)

この方法は非推奨で過去のPythonバージョンをサポートせざるを得ないシーンで使われるレガシーなやり方のようでした。
参考:名前空間パッケージをパッケージする - Python Packaging User Guide

Python 3.2と3.3での動作確認

pyenvで過去のPythonバージョンを実行しようとすると、OpenSSLの古い依存ライブラリを使うためビルドエラーになってしまった。
なので、古い依存ライブラリでビルドするDockerライブラリを準備して動作確認を行なっています。
GitHub - buzzword111/python-3.2-3.3-imports: レガシー Python (3.2.6 / 3.3.0) を Docker 上でビルド・実行するサンプル

Link

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?