2011-08-15 3 views
5

私は、ユーティリティタイプの関数とコアAPIの関数の間で半分に分かれたモジュールを持っています。私は、を便利にするために、それらのすべてを__all__に入れておく必要があります。また、モジュールの多くの関数/クラス/ etcを外部使用のために指定することもできますが、私はまた、from mymodule import *を他のモジュールへのコア機能だけです。それを行う方法はありますか?モジュール内の__all__から `from ... import * 'api seperateをどのように定義するのですか?

答えて

4

ほぼ。あなたは__all__は、このように二重の義務を行うことはできませんが、あなたがしてインポートすることができ、独自の仮想APIモジュールを追加することができます...

class fake_module(object): 
    def __init__(self, name, *args): 
     self.name = name 
     self.__all__ = [] 
     all_objects = globals() 
     for name in args: 
      self.__dict__[name] = all_objects[name] 
      self.__all__.append(name) 
    def register(self): 
     sys.modules["%s.%s" % (__name__, self.name)] = self 

    fake_module('api', 'class1', 'class2', 'func3', 'exception4').register() 

は、代わりにfrom mymodule import *の他のモジュールで、あなたはにfrom mymodule.api import *を行うことができます単一のモジュールにすべてを保持しながら、必要なサブセットだけを取得します。

from ... import *は通常は良い習慣ではありません、と細心の注意を払ってのみ明示的に、彼らは心の中でこのような使用して設計されていることを述べるモジュール/パッケージして使用する必要があります。

+0

ここに夢中になる必要は本当にありません。「api」という別のファイルを作成し、関数のサブセットをインポートして、モジュールの__init__.pyにインポートしてください。 – Dave

+0

@Dave:モジュールは単一のファイルなので、 '__init __。py'sはありません。パッケージは '__init __。py'ファイルを持っていなければなりませんし、他のファイルも持つことができます。私が開発しているライブラリは、1つのファイルに快適に収まります(はい、パッケージルートを試して、最終的に単一のファイル/モジュールレイアウトに戻しました)。 –

+0

フェア十分です。あなたがとったとき...:) – Dave

2

私はそれを行う方法はないと思います - 少なくともクリーンな方法ではありません。 Pythonの公式モジュールでさえ、ドキュメントに現れる多くのutil関数があります。分離が重要な場合は、2つの異なるモジュールを作成します。とにかく、from module import *を使うのは良い習慣ではありません。そのような練習に合うようにあなたのモジュールを設計することはずっと少なくて済みます。

+0

ユーザ定義のユーティリティモジュールの場合は、むしろ良い方法です。 – Evpok

+0

@Evpokユーザ定義のユーティリティモジュールとは何ですか?これらのモジュールはPythonコンソールで使用されますか? – brandizzi

+0

私はアプリケーション内のいたるところで使用されるショートカットや定数を持つモジュール、デフォルト値、マジックナンバー、汚れたハッキン​​グを意味しました... – Evpok

0

あなたが望むものはありません:import *__all__

+0

私は欲しいものではありませんが、かなり近づきます。 'from mymodule.api import *'は十分です。 –

4

Ethan、あなたのfake_moduleは、普通の古いPythonでうまくいく可能性が高いです。ただ、ディレクトリの設定にあなたのコードを移動:_mymodule.pyは、あなたの現在のコードが含まれています

mymodule 
    __init__.py 
    api.py 
    util.py 
    _mymodule.py 

。で

あなた__init__.py

from _mymodule import * 

あなたはapi.py

# explicity import only those api classes you want to expose 
# this will allow you to call `from mymodule.api import *` 
import from _mymodule ApiClass1 
import from _mymodule ApiClass2 
# etc 

はだから今、あなたのutil.py

# explicity import only those util classes you want to expose 
# this will allow you to call `from mymodule.util import *` 
import from _mymodule UtilClass1 
import from _mymodule UtilClass2 
# etc 

ために同じことを行いますでは次のことができます。

# import everything willy nilly for your help() 
from mymodule import * 

# or import only the "public" values from api and util 
from mymodule.api import * 
from mymodule.util import * 

このようにコードを分割すると、トップレベルの名前空間からアクセスできるようにしたいと考えている大規模なモジュールを整理するのに便利です。しかし、brandizziに同意する必要があります。このモジュールを使用しているコードでfrom mymodule import *を使用すると、一般的には悪い考えです。インポートの容易さで得たものは、それらのインポートを使用しているコードの透明性を失います。

+0

それは普通のやり方を詳細に徹底的に答えています。 –

関連する問題