24
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

しかし、同じエラーが発生しました。

どうすればこれを達成できますか?これも適切なアプローチですか?

編集:Python2の場合

4

6 に答える 6

28

もう少しいじった後、設定方法に気づきました。具体的には、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)をそのパッケージに移動すると、すべてがおかしなことになりました。

于 2011-01-11T09:46:41.760 に答える
14

ただし、Python PATHに「もの」が含まれていない限り、パスを追加する以外に選択肢はありません。

あなたが何かからあなたのscript.pyのレベルを知っているなら、あなたは例えばすることができます:

import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
于 2011-01-11T08:56:48.320 に答える
7

私はWindows7でPython3.4.2を実行していて、これで髪を引き裂きました。

これらのいずれかを実行する場合:

python -m unittest python -m unittest Discover

...「トップレベルパッケージを超えて相対インポートを試行しました」というエラーが発生します。

私にとって、解決策は私の[test_stock.py]に「..」をドロップすることでした。行は次のとおりでした:..stockimportStockから

次のように変更しました:在庫輸入在庫から

..そしてそれは動作します。

フォルダ構造:

C:\
  |
  +-- stock_alerter
             |
             +-- __init__.py
             +-- stock.py
             |
             \-- tests
                   |
                   +-- __init__.py
                   \-- test_stock.py
于 2015-05-15T15:28:40.787 に答える
1

import ..foo..stuff.mylib大丈夫なはず

EDITは拡張機能を削除しました

于 2011-01-11T08:26:44.103 に答える
1

PEPから、相対インポートを使用して、パッケージ化されていないファイルをインポートすることはできないようです。

__init__.pyしたがって、を追加して、インポートを次のようなものに変更する必要があります。from .mylib import *

ただし、PEPは、mylibをモジュールにパッケージ化しておくことを許可していないようです。そのため、ライブラリ関数の呼び出し方法を変更する必要がある場合があります。

もう1つの方法は、mylibをサブパッケージに移動し、次のようにインポートすることです。from .libpackage import mylib

于 2011-01-11T09:45:06.850 に答える
0

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のインポートを深く理解している必要はありません。

tests/
    common/
        commonlib.py
    test1/
        executable1.py
        executable2.py
        commonlib.py -> ../common/commonlib.py
    test2/
        executable1.py
        executable2.py
        commonlib.py -> ../common/commonlib.py


于 2019-02-05T14:23:05.103 に答える