python 別ファイル - サブディレクトリ内の異なるファイルからクラスをインポートする




作成 複数 (5)

私はこの簡単な方法を使用します:

  1. ディレクトリをシステムパスに追加してから、
  2. import moduleまたはfrom module import function1, class1からそのディレクトリをfrom module import function1, class1します。

moduleが拡張部分のない*.pyファイルの名前にすぎないことに注意してください。

一般的な例を次に示します。

import sys
sys.path.append("/path/to/folder/")
import module # in that folder

あなたの場合は、次のようなものになります。

import sys
sys.path.append("subdir/")
import myclass01
# or
from myclass01 import func1, class1, class2 # .. etc

ここで私が協力している構造は次のとおりです。

directory/
          script.py
          subdir/
                 __init__.py
                 myclass01.py
                 myclass02.py

私がしたいのは、 myclass01.pymyclass02.py定義されたクラスをscript.pyでインポートすることです。 私が行った場合:

from subdir.myclass01 import *

myclass01.py定義されているクラスでmyclass01.pyます。 しかし、このソリューションでは、 subdir内の異なるファイルに多くのクラスが定義されていて、それらのすべてをインポートしたい場合は、各ファイルに1行を入力する必要があります。 このためのショートカットが必要です。 私は試した:

from subdir.* import *

しかしそれはうまくいかなかった。

編集 :ファイルの内容は次のとおりです。

これは__init__.py (Apalalaが提案したように__all__を使用しています):

__all__ = ['MyClass01','MyClass02']

これはmyclass01.pyです:

class MyClass01:
    def printsomething():
        print 'hey'

これはmyclass02.pyです:

class MyClass02:
    def printsomething():
        print 'sup'

これはscript.pyです:

from subdir import *
MyClass01().printsomething()
MyClass02().printsomething()

これはscript.pyを実行しようとすると得られるトレースバックです:

File "script.py", line 1, in <module>
    from subdir import *
AttributeError: 'module' object has no attribute 'MyClass01'

そこで使われている名前はあなたの質問のディレクトリ構造に表示されている名前とは異なりますが、 名前空間とクラスという質問に対する私の答えを使うことができます。 __init__.py表示されていれば、 usepackage.pyスクリプトはこのように書かれていsubdirpackageはあなたの質問のsubdirにマップされ、 Class1myclass01などにマップされます)。

from package import *

print Class1
print Class2
print Class3

リビジョン(更新済み):

おっと、申し訳ありませんが、私の他の答えのコードでは、あなたが望むことはしません。パッケージサブモジュールの名前を自動的にインポートするだけです。 名前を付けた属性を各サブモジュールからインポートするには、さらにいくつかのコード行が必要です。 パッケージの__init__.pyファイルの修正版です(これはPython 3.4.1でも動作します):

def _import_package_files():
    """ Dynamically import all the public attributes of the python modules in this
        file's directory (the package directory) and return a list of their names.
    """
    import os
    exports = []
    globals_, locals_ = globals(), locals()
    package_path = os.path.dirname(__file__)
    package_name = os.path.basename(package_path)

    for filename in os.listdir(package_path):
        modulename, ext = os.path.splitext(filename)
        if modulename[0] != '_' and ext in ('.py', '.pyw'):
            subpackage = '{}.{}'.format(package_name, modulename) # pkg relative
            module = __import__(subpackage, globals_, locals_, [modulename])
            modict = module.__dict__
            names = (modict['__all__'] if '__all__' in modict else
                     [name for name in modict if name[0] != '_'])  # all public
            exports.extend(names)
            globals_.update((name, modict[name]) for name in names)

    return exports

if __name__ != '__main__':
    __all__ = ['__all__'] + _import_package_files()  # '__all__' in __all__

別の方法として、上記のファイルをパッケージディレクトリにある別の.pyモジュールファイルに入れて、パッケージの__init__.pyから次のように使用することもできます。

if __name__ != '__main__':
    from ._import_package_files import *  # defines __all__
    __all__.remove('__all__')  # prevent export (optional)

ファイルの名前は何でも、 _アンダースコアで始まるものでなければならないので、再帰的にimportしようとはしません。


あなたの最善の選択肢は、おそらく最高のスタイルではないが、すべてをパッケージのネームスペースにインポートすることです。

# this is subdir/__init__.py
from myclass01 import *
from myclass02 import *
from myclass03 import *

次に、他のモジュールでは、パッケージから直接必要なものをインポートできます。

from subdir import Class1

私は、この質問が答えられてから数ヶ月が経過していることを知っていますが、私は同じことを探していて、このページを走っていました。 私は選ばれた答えに満足していなかったので、私は自分の解決策を書いてしまい、私はそれを分かち合うと思った。 ここに私が思いついたものがあります:

# NOTE: The function name starts with an underscore so it doesn't get deleted by iself
def _load_modules(attr_filter=None):
    import os

    curdir = os.path.dirname(__file__)
    imports = [os.path.splitext(fname)[0] for fname in os.listdir(curdir) if fname.endswith(".py")]

    pubattrs = {}
    for mod_name in imports:
        mod = __import__(mod_name, globals(), locals(), ['*'], -1)

        for attr in mod.__dict__:
            if not attr.startswith('_') and (not attr_filter or attr_filter(mod_name, attr)):
                pubattrs[attr] = getattr(mod, attr)

    # Restore the global namespace to it's initial state
    for var in globals().copy():
        if not var.startswith('_'):
            del globals()[var]

    # Update the global namespace with the specific items we want
    globals().update(pubattrs)

# EXAMPLE: Only load classes that end with "Resource"
_load_modules(attr_filter=lambda mod, attr: True if attr.endswith("Resource") else False)
del _load_modules # Keep the namespace clean

これは、パッケージディレクトリ内のすべての.pyファイルから*を単純にインポートし、パブリックなものだけをグローバル名前空間にプルします。 さらに、特定のパブリック属性だけが必要な場合は、フィルタを使用できます。


場合によっては、定義されたポートとそのデータベースのサーバIPアドレスも重要です...

mysql -u user -p user -h <Server IP> -P<port> (DBNAME) < DB.sql 




python import