0

次のようなディレクトリ構造があるとします。

mydir
    __init__.py
    innerdir
        __init__.py
        mymodule.py

の内容は次のmymodule.pyとおりです。

def hi():
    print 'hello, welcome'

一方、両方__init__.pyの はです。

mydirディレクトリの外にいて、Python プロンプトを開いてimport mydirを使用しようとするとmydir.innerdir、エラー ( NameError: 'innerdir' is not defined) が発生します。

ディレクトリに移動した場合も同じで、mydirそこでプロンプトを表示して試してみてimport innerdirくださいinnerdir.mymodule

うまく使えますが、そのままではなく、としてimport mydir.innerdirしか使えません。mydir.innerdirinnerdir

4

2 に答える 2

3

あなたが説明したことのいくつかは、あなたが何を期待していたのかさえわかりません。しかし、あなたの最後の段落からすると、あなたはかなり近づいているように聞こえるので、そこから始めましょう.

mydir.innerdir を正常にインポートできますが、それを単に innerdir としてではなく、mydir.innerdir としてのみ使用できます。パス全体を指定する必要があるのはなぜですか?

これimportは、パッケージを無視してフラットなものがたくさんある場合や、標準ライブラリだけがある場合でも、Python で機能する方法です。たとえば、import osあなたなら、できますがos.listdir('.')、ただできるわけではありませんlistdir('.')

ここでの解決策は、そこにあるのと同じです。

from mydir import innerdir

innerdir直接定義されていないパッケージであるため、これは実際にはあまり役に立ちません。おそらく本当にやりたいことはfrom mydir.innerdir import mymodule. しかし、これはあなたが求めたことを行う方法です。


import mydir続いてmydir.innerdirが機能しない理由を知りたい場合は、説明できます。

チュートリアルのパッケージセクションから:

… のような構文を使用する場合import item.subitem.subsubitem、最後の項目を除く各項目はパッケージでなければなりません。最後の項目はモジュールまたはパッケージにすることができますが、前の項目で定義されたクラス、関数、または変数にすることはできません。

したがって、あなたがしていることは、何の役にも立たないはずです。しかし、それは実際に何をしますか?

パッケージをモジュールであるかのようにインポートします。これは、パッケージ自体で定義したもの (関数、クラス、さらにはモジュール) が のメンバーとして利用できることを意味しますmydir。ただし、パッケージ ディレクトリ内のサブパッケージまたはサブモジュールが自動的にインポートされるわけではありません。パッケージとしてではなく、モジュールとしてインポートしていることを思い出してください。


内部から実行した場合mydir(または PYTHONPATH に追加した場合) に何が起こるかについて質問している場合mydirは、パッケージではなく、モジュールとパッケージでいっぱいのディレクトリです (この場合、 1 つのパッケージのみinnerdir)。するのとほとんど同じfrom mydir import innerdirです。

于 2013-04-03T23:25:39.727 に答える
1

直接インポートされたパッケージは、サブパッケージまたはサブモジュールをその名前空間に自動的に配置しません。

>>> import mydir
>>> dir(mydir)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

(ここにはありませんのでご注意innerdirください。)

しかし、パッケージを介してインポートする場合、Python は名前空間を一緒に接続します。

>>> import mydir.innerdir
>>> dir(mydir)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'innerdir']
>>> dir(mydir.innerdir)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

( には がないことに注意してくださいmymodulemydir.innerdir)

__all__Python では、 のマジック変数を使用して、パッケージに自動的に含めるサブモジュールを明示的に指定できます__init__.pyが、デフォルトでは、コード内の__init__.pyコードを実行するだけで、他には何もしません。

次のいずれかを実行できます。

import mydir.innerdir.mymodule; mydir.innerdir.mymodule.hi()
from mydir.innerdir import mymodule; mymodule.hi()
from mydir.innerdir.mymodule import hi; hi()

__init__.pyまたは、ファイルを編集して__all__、ワイルドカード インポート用の変数を含めることもできます。

# file mydir/innerdir/__init__.py
print 'Running mydir/innerdir/__init__.py'
__all__ = ['mymodule']

次に、次のようなことができます。

from mydir.innerdir import *; mymodule.hi()

さらにクレイジーなことに、サブパッケージとモジュールを積極的にインポートできます (これはお勧めしません!):

# file mydir/__init__.py
print 'Running mydir/__init__.py'
import innerdir

# file mydir/innerdir/__init__.py
print 'Running mydir/innerdir/__init__.py'
import mymodule

今、これらは動作します:

import mydir; mydir.innerdir.mymodule.hi()
from mydir import innerdir; innerdir.mymodule.hi()

パッケージのドキュメントをブラッシュ アップすることをお勧めします。このドキュメントでは、これらすべてが説明されており、ここで示したものとまったく同じディレクトリ構造になっています。

于 2013-04-03T23:57:56.323 に答える