4

わかりました、例を挙げましょう(以下の元の質問)。

私が直面している問題を示す「myproject」というパッケージを作成しました。

  1. ここからパッケージをダウンロードしてください: https://dl.dropbox.com/u/11013311/myproject.zip
  2. パッケージをインストールします (例: sudo python setup.py development)
  3. Ipython セッションを開き、「import myproject」と入力します。
  4. 「myproject」と入力し始めると。タブを 2 回押して、使用可能なメソッド/値を取得します...、同じ問題を示す "myproject.myproject" が表示されます。

私が間違っていることを説明できる人はいますか?アンドリュー・アルコックからの回答は、それを修正するのに役立ちません。少なくとも、どこに問題があるのか​​ わかりません。

もちろん、このような単純な例では、パッケージ ファイルをそれほど複雑にする必要はありませんが__init__.py、私の実際のプロジェクトでは、.COOLmyproject.COOL

回答ありがとうございます。

編集: utapyngoに報奨金を授与しました。彼のソリューションが効果的であり、さらに何かを学んだからです (深いサブモジュールを使用した相対インポート)。しかし、 Andrewnehzの回答に感謝したいと思います ( nehzは私の問題を解決する解決策も提供してくれましたが、非常に主観的には「あまり美しくない」と感じました。Andrewは有用なアドバイスを提供してくれました)。賞金を分けられないのは残念です。

**

元の質問:

**

私は質問を正しく表現したかどうか確信が持てません。多数のサブパッケージを含む大きなコードを作成しました。簡単にするために、それを 'CODE' と呼びましょう。

問題は: 'CODE' が名前空間に表示されるので、CODE.CODEorCODE.CODE.CODEなどを無制限に持つことができます。警告なしに)。

問題は私__init__.pyとコードの構造に関係していると思われるので、ここでさらに情報を提供します。

簡素化されたコード構造:

CODE
  | __init__.py
  | tools
     | __init__.py
     | mytools.py
  | other
     | __init__.py
     | init.py
  | sub
     | __init__.py
     | module.py

ファイル: __init__.py(最初のもの、のルートにありCODEます)

import CODE.tools.mytools as MyTools
import CODE.other.init

OBJ = CODE.other.init.function()
...

このファイルは、CODE、またはインポートできるその他のモジュールからmytools.pyはインポートされません。 などのモジュールをインポートできます。最後に、のようなモジュールは、または(CODE から)のいずれかをインポートできます。通常、すべてのインポートは in: のように絶対インポートで行われます。OBJOBJinit.pymytools.pymodule.pymytools.pyOBJfrom CODE.sub.module import func

誰かがそのような行動の説明を持っていますか? SOに関する関連する質問は見つかりませんでしたが、私の言い回しが間違っている可能性があります。

4

3 に答える 3

3

問題は、インポートしたパッケージ(基本的には最上位の __init__.py ファイル) に、他のインポートの中にそれ自体 (モジュール) への参照が含まれていることです。モジュールにはそれ自体を含む名前空間が含まれるようになったため、CODE.CODE としてアクセスできるようになりました。... .CODE.MyTools.

私は提案します:

1) 各サブパッケージ (ツール、その他) に __init__.py を配置します。

2) CODE のモジュール内では、CODE やサブパッケージを「インポート」しないでください。代わりに、関心のあるモジュール (ファイル) を直接インポートしてください。

たとえば、CODE.sub.module.py では次のようになります。

しない:

import CODE.other     # "other" is a package (a directory)

行う:

import CODE.other.init    # "init" is a module (a file)

このように正気は嘘をつきます。

編集:あなたの特定の例をリフレーミング

ファイル mytools.py は、CODE から OBJ をインポートしたり、OBJ をインポートする可能性のある他のモジュールをインポートしたりしません。init.py は、mytools.py などのモジュールをインポートする場合があります。

わかった

最後に、module.py のようなモジュールは、mytools.py または OBJ (CODE から) のいずれかをインポートできます。

これはあなたの問題です。ここに CODE をインポートしないでください。かなり長い "CODE.other.init.function" を単純化する必要がある場合は、 from .. import ステートメントを使用して実行できます。

> from CODE.other.init import function as OBJ 

しかし、混乱を招くため、多くの Python 愛好家はこれを好まないことに注意してください。

通常、すべてのインポートは、次のように絶対インポートで行われます。 from CODE.sub.module import func.

わかった

于 2012-07-17T01:25:25.667 に答える
1

絶対インポートを使用した後、参照を削除するだけです。

import atexit

import myproject.mymodule_one.suby as SubY
obj = SubY.myclass()
import myproject.mymodule_two.initialization

COOL = myproject.mymodule_two.initialization.create_cool()
del myproject

編集:参考までに、参照を削除してもモジュールはアンロードされず、COOL のインスタンスは引き続き有効です。

于 2012-08-31T03:45:24.230 に答える
1

メイン__init__.pyでは、モジュール名を参照する必要はありませんし、参照すべきではありません (誰が知っているでしょうが、おそらく将来的に名前を変更したいと思うでしょう)。

交換するだけ

import myproject.mymodule_...

import mymodule_...

今はありませんmyproject.myproject

>>> dir(myproject)
['COOL', 'SubY', '__builtins__', '__doc__', '__file__', '__name__', '__package__',
 '__path__', '__version__', 'atexit', 'exit_report', 'mymodule_one', 'mymodule_two',
 'obj', 'toto']
于 2012-08-31T12:02:34.820 に答える