2

私のディレクトリ構造/VM/repo/projectは次のとおりです。

__init__.py

scripts/
      getSomething.py
      __init__.py

classes/
      project.py
      db.py
      __init__.py

getSomething.py

from ..classes import project
from ..classes import db

プロジェクト.py

class PROJECT:
def __init__(self):
    stuff

db.py

class DB:
def __init__(self):
    stuff

走ろうとすると

python getSomething.py

エラーが発生します

トレースバック (最後の最後の呼び出し):
ファイル "scripts/getSomething.py"、4 行目、< モジュール >
から ..classes インポート プロジェクト
ValueError: Attempted relative import in non-package

ここで何が欠けていますか?

4

1 に答える 1

5

getSomethingエラーに記載されているように、メイン モジュールとして実行しています。ただし、パッケージ内にいない場合は、パッケージの相対インポートを行うことはできません。メイン モジュールは決してパッケージに含まれません。getSomethingしたがって、パッケージの一部としてインポートする場合は...:

# /VM/repo/main.py
from project.scripts import getSomething

そうすれば、インポートエラーは発生しません。


おそらく、Python モジュールとパッケージについて簡単に議論することは役に立ちます。一般に、python ソース コードを含み、.py拡張子を持つファイルはモジュールです。通常、そのモジュールの名前はファイルの名前 (sans 拡張子) ですが、直接実行すると、そのモジュールの名前は'__main__'. これまでのところ、これはすべてよく知られており、文書化されています。モジュールをインポートするには、やるだけimport moduleですimport package.module。この最後の import ステートメントは、これから説明する何か (「パッケージ」) を参照しています...

パッケージは、インポートできるディレクトリです。多くのディレクトリはインポートできません (たとえば、Python ソース ファイル (モジュール) が含まれていない可能性があります)。したがって、このあいまいさを解決するために、ディレクトリにファイルがあるという要件もあり__init__.pyます。ファイルシステムにディレクトリをインポートすると、python は実際にモジュールをインポートし、 (存在する場合)__init__.py内のものから関連するパッケージを作成します。__init__.py

これらすべてをまとめる__init__.pyと、Python がモジュールをパッケージの一部と見なすのに十分ではないディレクトリ内でファイルを実行する理由が示されます。まず、モジュールの名前は__main__ではなくpackage.filename_sans_extensionです。第二に、パッケージの作成は、ファイルシステムの構造だけでなく、ディレクトリ (つまり、__init__.py実際にインポートされたもの) に依存します。

「なぜこのように設計したのか」と自問するかもしれません。実際、私は時々同じ質問を自問したことがあります。その理由は、言語設計者がパッケージに一定の保証を設けたいからだと思います。パッケージは、特定の目的のために連携するように設計されたものの単位である必要があります。いくつかのでたらめな__init__.pyファイルのおかげで、必要な他のモジュールを見つけるためにファイルシステムを歩き回る能力を得るスクリプトのサイロであってはなりません。何かがメイン モジュールとして実行されるように設計されている場合、それはおそらくパッケージの一部であってはなりません。むしろ、パッケージをインポートしてそれに依存する別のモジュールにする必要があります。

于 2016-06-28T17:40:08.480 に答える