テクノロジー · 実用ガイド

attempted relative import with no known parent package?まず実行コンテキストを証明

先頭のドットより、ファイルがどう起動されたかが重要です。__package__ と __spec__ を記録し、パッケージモジュール、インストール済みコマンド、単独スクリプトのどれか一つを選びます。

Python ファイルの直接実行と python -m によるパッケージ実行のメタデータを比較するオリジナル図。
オリジナル編集イラスト:直接実行では親パッケージがなく、-m ではパッケージ識別情報を持てます。 Watch at Ease

失敗したのと同じコマンドを実行し、インポートを変える前に __name__、__package__、__spec__、sys.argv、作業ディレクトリ、sys.path[0] を出力します。パッケージのようなフォルダ内にあるファイルでも、最上位の __main__ として実行されることがあります。Python の文書では、ソースファイルを直接実行すると __main__.__spec__ は None になり、先頭のドットを解決する親パッケージが記録されません。

恒久対策はドットの数を試すことではありません。コードをパッケージモジュール、インストール済みコマンド、単独スクリプトのどれとして提供するか決めます。トップレベルパッケージを含むディレクトリから python -m package.module を使う、[project.scripts] でコマンドを作る、または薄い起動スクリプトをパッケージ外に置き絶対インポートします。最後に同じコマンドを再実行し、モジュールの場所とパッケージ情報を終了証拠にします。

1. 代替コマンドではなく失敗した起動を記録

失敗したのと同じコマンドを実行し、インポートを変える前に __name__、__package__、__spec__、sys.argv、作業ディレクトリ、sys.path[0] を出力します。パッケージのようなフォルダ内にあるファイルでも、最上位の __main__ として実行されることがあります。Python の文書では、ソースファイルを直接実行すると __main__.__spec__ は None になり、先頭のドットを解決する親パッケージが記録されません。 ソースファイルの直接実行では、インポート可能なファイルでも __main__.__spec__ は None です。

恒久対策はドットの数を試すことではありません。コードをパッケージモジュール、インストール済みコマンド、単独スクリプトのどれとして提供するか決めます。トップレベルパッケージを含むディレクトリから python -m package.module を使う、[project.scripts] でコマンドを作る、または薄い起動スクリプトをパッケージ外に置き絶対インポートします。最後に同じコマンドを再実行し、モジュールの場所とパッケージ情報を終了証拠にします。 python -m は標準のインポート機構でモジュールを探し、モジュール情報を設定します。

2. パッケージルートと完全修飾名を証明

失敗したのと同じコマンドを実行し、インポートを変える前に __name__、__package__、__spec__、sys.argv、作業ディレクトリ、sys.path[0] を出力します。パッケージのようなフォルダ内にあるファイルでも、最上位の __main__ として実行されることがあります。Python の文書では、ソースファイルを直接実行すると __main__.__spec__ は None になり、先頭のドットを解決する親パッケージが記録されません。 python -m は標準のインポート機構でモジュールを探し、モジュール情報を設定します。

恒久対策はドットの数を試すことではありません。コードをパッケージモジュール、インストール済みコマンド、単独スクリプトのどれとして提供するか決めます。トップレベルパッケージを含むディレクトリから python -m package.module を使う、[project.scripts] でコマンドを作る、または薄い起動スクリプトをパッケージ外に置き絶対インポートします。最後に同じコマンドを再実行し、モジュールの場所とパッケージ情報を終了証拠にします。 相対インポートはフォルダの見た目ではなく、現在のモジュールのパッケージ名を基準に解決されます。

3. 入口の契約を一つだけ選ぶ

失敗したのと同じコマンドを実行し、インポートを変える前に __name__、__package__、__spec__、sys.argv、作業ディレクトリ、sys.path[0] を出力します。パッケージのようなフォルダ内にあるファイルでも、最上位の __main__ として実行されることがあります。Python の文書では、ソースファイルを直接実行すると __main__.__spec__ は None になり、先頭のドットを解決する親パッケージが記録されません。 相対インポートはフォルダの見た目ではなく、現在のモジュールのパッケージ名を基準に解決されます。

恒久対策はドットの数を試すことではありません。コードをパッケージモジュール、インストール済みコマンド、単独スクリプトのどれとして提供するか決めます。トップレベルパッケージを含むディレクトリから python -m package.module を使う、[project.scripts] でコマンドを作る、または薄い起動スクリプトをパッケージ外に置き絶対インポートします。最後に同じコマンドを再実行し、モジュールの場所とパッケージ情報を終了証拠にします。 作業ディレクトリを変えるだけでは、直接ファイル実行はパッケージ実行になりません。

4. 事故を移すだけの修正を避ける

失敗したのと同じコマンドを実行し、インポートを変える前に __name__、__package__、__spec__、sys.argv、作業ディレクトリ、sys.path[0] を出力します。パッケージのようなフォルダ内にあるファイルでも、最上位の __main__ として実行されることがあります。Python の文書では、ソースファイルを直接実行すると __main__.__spec__ は None になり、先頭のドットを解決する親パッケージが記録されません。 作業ディレクトリを変えるだけでは、直接ファイル実行はパッケージ実行になりません。

恒久対策はドットの数を試すことではありません。コードをパッケージモジュール、インストール済みコマンド、単独スクリプトのどれとして提供するか決めます。トップレベルパッケージを含むディレクトリから python -m package.module を使う、[project.scripts] でコマンドを作る、または薄い起動スクリプトをパッケージ外に置き絶対インポートします。最後に同じコマンドを再実行し、モジュールの場所とパッケージ情報を終了証拠にします。 インストール済み project script はインポート可能な関数を呼び、内部ファイルをコマンド境界にしません。

5. 診断を消す前に終了証拠を定義

失敗したのと同じコマンドを実行し、インポートを変える前に __name__、__package__、__spec__、sys.argv、作業ディレクトリ、sys.path[0] を出力します。パッケージのようなフォルダ内にあるファイルでも、最上位の __main__ として実行されることがあります。Python の文書では、ソースファイルを直接実行すると __main__.__spec__ は None になり、先頭のドットを解決する親パッケージが記録されません。 インストール済み project script はインポート可能な関数を呼び、内部ファイルをコマンド境界にしません。

恒久対策はドットの数を試すことではありません。コードをパッケージモジュール、インストール済みコマンド、単独スクリプトのどれとして提供するか決めます。トップレベルパッケージを含むディレクトリから python -m package.module を使う、[project.scripts] でコマンドを作る、または薄い起動スクリプトをパッケージ外に置き絶対インポートします。最後に同じコマンドを再実行し、モジュールの場所とパッケージ情報を終了証拠にします。 終了証拠は実際の起動コマンドを繰り返し、期待するパッケージ情報とインポート元を記録します。

Python のパッケージモジュールと単独スクリプトの入口を選び、結果を検証するオリジナル判断図。
オリジナル編集イラスト:入口契約を一つ選び、同じコマンドで意図したモジュールを確認します。 Watch at Ease