stuff/
__init__.py
mylib.py
Foo/
__init__.py
main.py
foo/
__init__.py
script.py
script.py
インポートしたいmylib.py
これは単なる例ですが、実際には、親ディレクトリにあるモジュールの相対インポートを実行したいだけです。私はさまざまなことを試しましたが、このエラーが発生しました...
Attempted relative import beyond toplevel package
プログラムの開始点からのスクリプトがパッケージに含まれてはならないことをどこかで読んだので、そのように構造を変更してみました...
stuff/
mylib.py
foo.py // equivalent of main.py in above
foo/
__init__.py
script.py
しかし、同じエラーが発生しました。
どうすればこれを達成できますか?これは適切なアプローチですか?
編集:In Python 2
もう少しいじってみたところ、設定方法がわかりました。具体的にするために、fooバー名は使用しません。私のプロジェクトディレクトリは次のように設定されています...
tools/
core/
object_editor/
# files that need to use ntlib.py
editor.py # see example at bottom
__init__.py
state_editor/
# files that need to use ntlib.py
__init__.py
ntlib.py
__init__.py # core is the top level package
LICENSE
state_editor.py # equivalent to main.py for the state editor
object_editor.py # equivalent to main.py for the object editor
object_editor.py
の行は次のようになります...
from core.object_editor import editor
editor.py
の行は次のようになります...
from .. import ntlib
または代わりに
from core import ntlib
重要なのは、質問で挙げた例では、「メイン」スクリプトがパッケージ内から実行されていたということです。移動して特定のパッケージ(core
)を作成し、エディターに共有してほしいライブラリ(ntlib
)をそのパッケージに移動すると、すべてがおかしくなりました。
python PATHに「もの」が含まれていない限り、パスを追加する以外に選択肢はありませんでした。
たとえば、script.pyのレベルがわかっている場合は、次のようにできます。
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
私はWindows 7でPython 3.4.2を実行しています。これで髪の毛を引き裂きました。
これらのいずれかを実行する場合:
python -m unittest python -m unittest discover
...「トップレベルパッケージを超えて相対インポートを試みました」というエラーが表示されます。
私にとって、解決策は[..]を[test_stock.py]にドロップすることでした。ラインは:..stock import Stockから
変更:在庫インポートから
..そしてそれは動作します。
フォルダー構造:
C:\
|
+-- stock_alerter
|
+-- __init__.py
+-- stock.py
|
\-- tests
|
+-- __init__.py
\-- test_stock.py
[〜#〜] pep [〜#〜] から、相対インポートを使用して、パッケージ化されていないファイルをインポートすることはできないようです。
したがって、__init__.py
を追加して、インポートをfrom .mylib import *
のようなものに変更する必要があります。
ただし、PEPはmylibをモジュールにパッケージ化しておくことを許可していないようです。したがって、ライブラリ関数の呼び出し方法を変更する必要がある場合があります。
もう1つの方法は、mylibをサブパッケージに移動し、from .libpackage import mylib
としてインポートすることです。
import ..foo..stuff.mylib
大丈夫なはず
EDITは拡張機能を脱いだ
Linuxまたはおそらく* nixを使用している場合は、これをシンボリックリンクでハックできます。
stuff/
mylib.py
foo.py // equivalent of main.py in above
foo/
script.py
mylib.py -> ../mylib.py
foo2/
script2.py
mylib.py -> ../mylib.py
これは、おそらく従うのに適したパターンではありません。
私の場合、別のディレクトリに配置する必要がある同じライブラリに依存する複数の実行可能ファイルがあったので、それを選択しました。
新しい実行可能テストの実装では、テスト作成者がpython importsを深く理解している必要はありません。
tests/
common/
commonlib.py
test1/
executable1.py
executable2.py
commonlib.py -> ../common/commonlib.py
test2/
executable1.py
executable2.py
commonlib.py -> ../common/commonlib.py