1

ここにpythonモジュールがあります。fooですsys.path

foo\
    __init__.py
    bar\
        __init__.py
        base.py
            class Base(object)
        derived.py
            import foo.bar.base as base
            class Derived(base.Base)

私はまだ空想的なことは何もしていません。モジュールからDerivedクラスをインスタンス化する場合derivedは、簡単に実行できます。

import foo.bar.derived as derived
print(derived.Derived())

ただし、barモジュールをインポートして を呼び出すだけにしたいと思いbar.Derived()ます。これは、さまざまなモジュール内に多数のクラスを配置する予定であり、これらすべての触角的なインポート パスを処理したくないためです。私の理解では、プロジェクトを次のように変更することで、 Derivedをモジュールの名前空間に簡単にインポートできます。bar

foo\
    __init__.py
    bar\
        __init__.py
            from foo.bar.derived import Derived
        base.py
            class Base(object)
        derived.py
            import foo.bar.base as base
            class Derived(base.Base)

これで、次のことができるはずです。

import foo.bar as bar
print(bar.Derived())

fooしかし、モジュールに と呼ばれるサブモジュールがないことを訴える AttributeError が表示されbarます。

test.py             (1): import foo.bar
foo\bar\__init__.py (1): from foo.bar.derived import Derived
foo\bar\derived.py  (1): import foo.bar.base as base

AttributeError: 'module' object has no attribute 'bar'

実際、私の元のテスト コード (上部) も機能しません。インポートしようとするとすぐにfoo.barエラーが発生します。

このエラーからわかるのは、__init__.py原因の import ステートメントが完全にロードderived.pyされる前に実行されるため、独自の基本クラスを含むbarモジュールを (これも から) インポートできないことです。bar私は C++ の世界から来ました。ここでは、超ネストされた名前空間は統合されておらず、単純な前方宣言でこの問題は解消されますが、私が探していることが可能であり、少なくともある程度受け入れられるPythonicソリューション。私は何を間違っていますか?サブモジュールのクラスを親モジュールの名前空間で使用できるようにする正しい方法は何ですか?

4

2 に答える 2

5

Python 2.5 以降を使用している場合は、明示的な相対インポート ( http://www.python.org/dev/peps/pep-0328/#guido-s-decision )を使用してみてください。

test.py             (1): import foo.bar
foo\bar\__init__.py (1): from .derived import Derived
foo\bar\derived.py  (1): from . import base

from __future__ import absolute_import(実際に Python 2.5 または 2.6 を使用している場合は、モジュールに含める必要があることに注意してください。)

于 2012-06-06T21:22:35.703 に答える
1

派生した.pyでは、これを使用します:

EDIT : JAB が指摘したように、暗黙的な相対インポートは非​​推奨であり、以下は推奨されません (ただし、Python 2.7 でも動作しますが、非推奨エラーはありません!)。

import base # 必要なのはこれだけです - 現在のディレクトリにあります

代わりに、次を使用します。

from . import base # 

(また)

from foo.bar import base

それ以外の:

import foo.bar.base as base

これにより、両方のエラーが解決されます(同じ問題からのものであるため)。basefoo.bar.base モジュール内に関数またはクラスがないため、インポートは機能しません。

于 2012-06-06T21:42:00.833 に答える