1504

フルパスを指定してPythonモジュールをロードするにはどうすればよいですか?

ファイルは構成オプションであるため、ファイルシステムのどこにでも配置できることに注意してください。

4

35 に答える 35

1566

Python 3.5 以降の場合:

import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
foo.MyClass()

Python 3.3 および 3.4 の場合:

from importlib.machinery import SourceFileLoader

foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()

(ただし、これは Python 3.4 で廃止されました。)

Python 2 の場合:

import imp

foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()

コンパイルされた Python ファイルと DLL には、同等の便利な関数があります。

http://bugs.python.org/issue21436も参照してください。

于 2008-09-15T22:41:16.887 に答える
514

(imp を使用するよりも) sys.path にパスを追加する利点は、単一のパッケージから複数のモジュールをインポートするときに物事が単純化されることです。例えば:

import sys
# the mock-0.3.1 dir contains testcase.py, testutils.py & mock.py
sys.path.append('/foo/bar/mock-0.3.1')

from testcase import TestCase
from testutils import RunTests
from mock import Mock, sentinel, patch
于 2008-09-24T19:36:16.357 に答える
86

最上位モジュールがファイルではなく、__init__.py を使用してディレクトリとしてパッケージ化されている場合、受け入れられているソリューションはほとんど機能しますが、完全ではありません。Python 3.5 以降では、次のコードが必要です (「sys.modules」で始まる行が追加されていることに注意してください)。

MODULE_PATH = "/path/to/your/module/__init__.py"
MODULE_NAME = "mymodule"
import importlib
import sys
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module 
spec.loader.exec_module(module)

この行がないと、exec_module が実行されると、最上位の __init__.py の相対インポートを最上位のモジュール名 (この場合は "mymodule") にバインドしようとします。ただし、「mymodule」はまだロードされていないため、「SystemError: 親モジュール 'mymodule' がロードされていないため、相対インポートを実行できません」というエラーが発生します。そのため、ロードする前に名前をバインドする必要があります。この理由は、相対インポート システムの基本的な不変条件です。 )、後者は前者の foo 属性として表示される必要があります"ここで説明したように.

于 2018-05-17T15:23:41.610 に答える
44

構成ファイルを特にインポートしたくないようです (これには、多くの副作用と追加の複雑さが伴います)。それを実行して、結果の名前空間にアクセスできるようにしたいだけです。標準ライブラリは、runpy.run_pathの形式で専用の API を提供します。

from runpy import run_path
settings = run_path("/path/to/file.py")

このインターフェイスは、Python 2.7 および Python 3.2+ で使用できます。

于 2016-05-20T06:52:17.230 に答える
23

このようなことをして、構成ファイルが置かれているディレクトリをPythonロードパスに追加し、ファイルの名前(この場合は「config」)を事前に知っていると仮定して、通常のインポートを行うこともできます。

散らかっていますが、動作します。

configfile = '~/config.py'

import os
import sys

sys.path.append(os.path.dirname(os.path.expanduser(configfile)))

import config
于 2008-09-15T22:44:50.980 に答える
18

ロードまたはインポートを意味しますか?

リストを操作sys.pathしてモジュールへのパスを指定してから、モジュールをインポートできます。たとえば、次のモジュールがあるとします。

/foo/bar.py

あなたができること:

import sys
sys.path[0:0] = ['/foo'] # Puts the /foo directory at the start of your path
import bar
于 2008-09-15T22:46:35.877 に答える
18

を使用できます。

load_source(module_name, path_to_file)

imp モジュールのメソッド。

于 2008-09-15T22:41:24.127 に答える
17

これは、2.7 から 3.5 までのすべての Python バージョン、およびおそらく他のバージョンでも機能するコードです。

config_file = "/tmp/config.py"
with open(config_file) as f:
    code = compile(f.read(), config_file, 'exec')
    exec(code, globals(), locals())

私はそれをテストしました。見苦しいかもしれませんが、今のところすべてのバージョンで動作するのはこれだけです。

于 2016-06-03T10:04:52.653 に答える
13

__import__と を使用してこれを行うことができますchdir

def import_file(full_path_to_module):
    try:
        import os
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)
        save_cwd = os.getcwd()
        os.chdir(module_dir)
        module_obj = __import__(module_name)
        module_obj.__file__ = full_path_to_module
        globals()[module_name] = module_obj
        os.chdir(save_cwd)
    except Exception as e:
        raise ImportError(e)
    return module_obj


import_file('/home/somebody/somemodule.py')
于 2008-09-16T01:43:04.407 に答える
9

imp.find_module()と を使用しimp.load_module()て、指定されたモジュールをロードできると思います。モジュール名をパスから分割する必要があります。つまり、ロードする場合は、次のように/home/mypath/mymodule.pyする必要があります。

imp.find_module('mymodule', '/home/mypath/')

...しかし、それは仕事を成し遂げるはずです。

于 2008-09-15T22:37:24.447 に答える
7

pkgutilモジュール (具体的にはメソッド) を使用walk_packagesして、現在のディレクトリ内のパッケージのリストを取得できます。そこから、importlib機械を使用して必要なモジュールをインポートするのは簡単です。

import pkgutil
import importlib

packages = pkgutil.walk_packages(path='.')
for importer, name, is_package in packages:
    mod = importlib.import_module(name)
    # do whatever you want with module now, it's been imported!
于 2014-09-13T19:57:28.967 に答える
5

Python 3.4 のこの領域は、理解するのが非常に難しいようです! しかし、Chris Calloway のコードを使って少しハッキングしたところ、何とか機能させることができました。基本機能はこちら。

def import_module_from_file(full_path_to_module):
    """
    Import a module given the full path/filename of the .py file

    Python 3.4

    """

    module = None

    try:

        # Get module name and path from full path
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)

        # Get module "spec" from filename
        spec = importlib.util.spec_from_file_location(module_name,full_path_to_module)

        module = spec.loader.load_module()

    except Exception as ec:
        # Simple error printing
        # Insert "sophisticated" stuff here
        print(ec)

    finally:
        return module

これは、Python 3.4 の非推奨でないモジュールを使用しているようです。理由を理解しているふりはしませんが、プログラム内から機能するようです。Chris のソリューションはコマンド ラインでは機能しますが、プログラム内からは機能しないことがわかりました。

于 2015-04-12T12:22:56.293 に答える
4

優れていると言っているわけではありませんが、完全を期すために、execPython 2 と Python 3 の両方で利用できる関数を提案したいと思います。

exec辞書として提供されるグローバル スコープまたは内部スコープのいずれかで、任意のコードを実行できます。

たとえば"/path/to/module、関数を使用して " に格納されたモジュールがある場合foo()、次のようにして実行できます。

module = dict()
with open("/path/to/module") as f:
    exec(f.read(), module)
module['foo']()

これにより、コードを動的にロードしていることがもう少し明確になり、カスタムのビルトインを提供する機能など、いくつかの追加機能が付与されます。

また、キーではなく属性を介してアクセスすることが重要な場合は、そのようなアクセスを提供するグローバル用のカスタム dict クラスを設計できます。

class MyModuleClass(dict):
    def __getattr__(self, name):
        return self.__getitem__(name)
于 2015-06-02T19:57:46.677 に答える
4

を使ったパッケージを作りましたimp。私はそれを呼び出しimport_file、これが使用方法です:

>>>from import_file import import_file
>>>mylib = import_file('c:\\mylib.py')
>>>another = import_file('relative_subdir/another.py')

次の場所で入手できます。

http://pypi.python.org/pypi/import_file

または

http://code.google.com/p/import-file/

于 2011-06-08T19:41:29.240 に答える
3

実行時にパッケージモジュールをインポートする(Pythonレシピ)

http://code.activestate.com/recipes/223972/

###################
##                #
## classloader.py #
##                #
###################

import sys, types

def _get_mod(modulePath):
    try:
        aMod = sys.modules[modulePath]
        if not isinstance(aMod, types.ModuleType):
            raise KeyError
    except KeyError:
        # The last [''] is very important!
        aMod = __import__(modulePath, globals(), locals(), [''])
        sys.modules[modulePath] = aMod
    return aMod

def _get_func(fullFuncName):
    """Retrieve a function object from a full dotted-package name."""

    # Parse out the path, module, and function
    lastDot = fullFuncName.rfind(u".")
    funcName = fullFuncName[lastDot + 1:]
    modPath = fullFuncName[:lastDot]

    aMod = _get_mod(modPath)
    aFunc = getattr(aMod, funcName)

    # Assert that the function is a *callable* attribute.
    assert callable(aFunc), u"%s is not callable." % fullFuncName

    # Return a reference to the function itself,
    # not the results of the function.
    return aFunc

def _get_class(fullClassName, parentClass=None):
    """Load a module and retrieve a class (NOT an instance).

    If the parentClass is supplied, className must be of parentClass
    or a subclass of parentClass (or None is returned).
    """
    aClass = _get_func(fullClassName)

    # Assert that the class is a subclass of parentClass.
    if parentClass is not None:
        if not issubclass(aClass, parentClass):
            raise TypeError(u"%s is not a subclass of %s" %
                            (fullClassName, parentClass))

    # Return a reference to the class itself, not an instantiated object.
    return aClass


######################
##       Usage      ##
######################

class StorageManager: pass
class StorageManagerMySQL(StorageManager): pass

def storage_object(aFullClassName, allOptions={}):
    aStoreClass = _get_class(aFullClassName, StorageManager)
    return aStoreClass(allOptions)
于 2008-09-15T22:43:20.953 に答える
3

これはうまくいくはずです

path = os.path.join('./path/to/folder/with/py/files', '*.py')
for infile in glob.glob(path):
    basename = os.path.basename(infile)
    basename_without_extension = basename[:-3]

    # http://docs.python.org/library/imp.html?highlight=imp#module-imp
    imp.load_source(basename_without_extension, infile)
于 2012-01-04T02:17:21.483 に答える
2

非常に簡単な方法: 相対パス ../../MyLibs/pyfunc.py でファイルをインポートしたいとします。

libPath = '../../MyLibs'
import sys
if not libPath in sys.path: sys.path.append(libPath)
import pyfunc as pf

しかし、ガードなしでそれを行うと、最終的に非常に長いパスを取得できます.

于 2018-01-26T04:52:15.063 に答える
1

これらは、pathlib のみを使用する私の 2 つのユーティリティ関数です。パスからモジュール名を推測します。

デフォルトでは、フォルダーからすべての Python ファイルを再帰的に読み込み、init .py を親フォルダー名に置き換えます。ただし、パスやグロブを指定して特定のファイルを選択することもできます。

from pathlib import Path
from importlib.util import spec_from_file_location, module_from_spec
from typing import Optional


def get_module_from_path(path: Path, relative_to: Optional[Path] = None):
    if not relative_to:
        relative_to = Path.cwd()

    abs_path = path.absolute()
    relative_path = abs_path.relative_to(relative_to.absolute())
    if relative_path.name == "__init__.py":
        relative_path = relative_path.parent
    module_name = ".".join(relative_path.with_suffix("").parts)
    mod = module_from_spec(spec_from_file_location(module_name, path))
    return mod


def get_modules_from_folder(folder: Optional[Path] = None, glob_str: str = "*/**/*.py"):
    if not folder:
        folder = Path(".")

    mod_list = []
    for file_path in sorted(folder.glob(glob_str)):
        mod_list.append(get_module_from_path(file_path))

    return mod_list
于 2020-08-09T23:20:27.320 に答える
1

Cなどのようなファイルをロードする方法は次のとおりです。

from importlib.machinery import SourceFileLoader
import os

def LOAD(MODULE_PATH):
    if (MODULE_PATH[0] == "/"):
        FULL_PATH = MODULE_PATH;
    else:
        DIR_PATH = os.path.dirname (os.path.realpath (__file__))
        FULL_PATH = os.path.normpath (DIR_PATH + "/" + MODULE_PATH)

    return SourceFileLoader (FULL_PATH, FULL_PATH).load_module ()

実装:

Y = LOAD("../Z.py")
A = LOAD("./A.py")
D = LOAD("./C/D.py")
A_ = LOAD("/IMPORTS/A.py")

Y.DEF();
A.DEF();
D.DEF();
A_.DEF();

各ファイルは次のようになります。

def DEF():
    print("A");
于 2021-02-13T01:06:29.487 に答える