it-swarm-ko.tech

전체 경로가 지정된 모듈을 가져 오는 방법은 무엇입니까?

전체 경로가 주어지면 어떻게 파이썬 모듈을로드 할 수 있습니까? 파일은 구성 옵션이므로 파일 시스템의 어느 위치 에나있을 수 있습니다.

922
derfred

파이썬 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에서는 더 이상 사용되지 않습니다.)

파이썬 2의 경우 :

import imp

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

컴파일 된 Python 파일과 DLL에 대해 동일한 편의 기능이 있습니다.

http://bugs.python.org/issue21436 를 참조하십시오.

1055
Sebastian Rittau

Sys.path (imp를 사용하는 것)에 경로를 추가하는 이점은 단일 패키지에서 둘 이상의 모듈을 가져올 때 작업을 단순화한다는 것입니다. 예 :

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
358
Daryl Spitzer

또한 이와 같은 작업을 수행하고 구성 파일이있는 디렉토리를 Python로드 경로에 추가 한 다음 미리 파일 이름 (이 경우 "config")을 알고 있다고 가정하고 일반적인 가져 오기를 수행 할 수 있습니다.

지저분하지만 작동합니다.

configfile = '~/config.py'

import os
import sys

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

import config
19
ctcherry

구성 파일 (많은 부작용과 복잡한 문제가 있음)을 특별히 가져오고 싶지 않고 실행 만하고 결과로 나오는 네임 스페이스에 액세스 할 수있게하려는 것 같습니다. 표준 라이브러리는 runpy.run_path 형태로 API를 제공합니다.

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

이 인터페이스는 Python 2.7 및 Python 3.2 이상에서 사용할 수 있습니다.

19
ncoghlan

당신은

load_source(module_name, path_to_file) 

imp 모듈 에서 메소드.

16
zuber

@ SebastianRittau의 훌륭한 답변 (Python> 3.4라고 생각합니다)의 약간 수정 된 버전을 생각해 냈습니다. 확장자를 가진 파일을 모듈로로드 할 수 있습니다 spec_from_loader 대신 spec_from_file_location 사용 :

from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader 

spec = spec_from_loader("module.name", SourceFileLoader("module.name", "/path/to/file.py"))
mod = module_from_spec(spec)
spec.loader.exec_module(mod)

명시 적 SourceFileLoader 에서 경로를 인코딩하면 machinery 가 확장명에서 파일 형식을 알아 내지 않습니다. 이는이 메소드를 사용하여 .txt 파일과 같은 것을로드 할 수 있지만 spec_from_file_location.txt 에 없기 때문에 로더를 지정하지 않고 importlib.machinery.SOURCE_SUFFIXES로 파일을로드 할 수 없음을 의미합니다.

13
Mad Physicist

로드 또는 가져 오기를 의미합니까?

Sys.path 목록을 조작하여 모듈 경로를 지정한 다음 모듈을 가져올 수 있습니다. 예를 들어, 주어진 모듈은 :

/foo/bar.py

할 수있는 일 :

import sys
sys.path[0:0] = ['/foo'] # puts the /foo directory at the start of your path
import bar
12
Wheat

최상위 모듈이 파일이 아니고 __init__.py가있는 디렉토리로 패키지되어 있다면 수용된 솔루션은 거의 작동하지만 거의 작동하지는 않습니다. 파이썬 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'이로드되지 않았고 상대 가져 오기를 수행 할 수 없습니다. '라는 오류가 발생합니다. 따라서로드하기 전에 이름을 바인딩해야합니다. 그 이유는 상대적 가져 오기 시스템의 근본적인 불변량입니다. "불변 보유는 sys.modules [ 'spam'] 및 sys.modules [ 'spam.foo']가있는 경우입니다 (위의 가져 오기 이후와 마찬가지로 ), 후자는 전자의 foo 속성으로 나타나야한다 " 여기에서 논의 된 것처럼 .

12
Sam Grondahl

모듈을 임포트하려면 임시 또는 영구적으로 디렉토리를 환경 변수에 추가해야합니다.

일시적으로

import sys
sys.path.append("/path/to/my/modules/")
import my_module

영구히

.bashrc 파일 (Linux)에 다음 행을 추가하고 터미널에서 source ~/.bashrc를 종료하십시오.

export PYTHONPATH="${PYTHONPATH}:/path/to/my/modules/"

신용/출처 : saarrrr , 다른 stackexchange 질문

11
Miladiouss

다음은 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())

나는 그것을 시험했다. 추악 할 수도 있지만 지금까지는 모든 버전에서 작동하는 유일한 버전입니다.

11
sorin
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:
        raise ImportError

import_file('/home/somebody/somemodule.py')
10
Chris Calloway

나는 imp.find_module()imp.load_module() 를 사용하여 지정된 모듈을로드 할 수 있다고 생각합니다. 모듈 이름을 경로에서 분리해야합니다. 예를 들어 /home/mypath/mymodule.py을로드하려면 다음을 수행해야합니다.

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

...하지만 그 일을 끝내야합니다.

8
Matt

파이썬 모듈 만들기 test.py

import sys
sys.path.append("<project-path>/lib/")
from tes1 import Client1
from tes2 import Client2
import tes3

Test_check.py 파이썬 모듈 만들기

from test import Client1
from test import Client2
from test import test3

가져온 모듈을 모듈에서 가져올 수 있습니다.

3
abhimanyu

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!
3
bob_twinkles

이것은 효과가있다.

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)
3
Hengjie

그게 더 낫다는 말은 아니지만, 완벽을 기하기 위해 파이썬 2와 3에서 사용할 수있는 exec function을 제안하고 싶었습니다. exec은 전역 범위, 또는 내부 범위에서 사전으로 제공됩니다.

예를 들어, 함수가 foo() 인 모듈을 "/path/to/module에 저장 한 경우 다음을 수행하여 실행할 수 있습니다.

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)
3
yoniLavi

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에서 비 deprecated 모듈을 사용하는 것으로 보입니다. 나는 그 이유를 이해하지 못하는 척하지만 프로그램 내에서 작동하는 것처럼 보입니다. Chris의 솔루션이 명령 줄에서는 작동하지만 프로그램 내부에서는 작동하지 않는다는 것을 알았습니다.

3
Redlegjed

지정된 파일 이름에서 모듈을 가져 오려면 임시로 경로를 확장하고 finally 블록에서 시스템 경로를 복원 할 수 있습니다. reference :

filename = "directory/module.py"

directory, module_name = os.path.split(filename)
module_name = os.path.splitext(module_name)[0]

path = list(sys.path)
sys.path.insert(0, directory)
try:
    module = __import__(module_name)
finally:
    sys.path[:] = path # restore
3
Peter Zhu

런타임에 패키지 모듈 가져 오기 (Python recipe)

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)
2
user10370

리눅스에서는 python 스크립트가 위치한 디렉토리에 심볼릭 링크를 추가합니다.

즉 :

ln -s /absolute/path/to/module/module.py /absolute/path/to/script/module.py

파이썬은 /absolute/path/to/script/module.pyc를 생성하고 /absolute/path/to/module/module.py의 내용을 변경하면이를 업데이트합니다

mypythonscript.py에 다음을 포함시킵니다.

from module import *
2
user2760152

나는 당신을 위해 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/

2
ubershmekel

아주 간단한 방법 : 상대 경로 ../../MyLibs/pyfunc.py로 파일 가져 오기를 원한다고 가정하십시오.


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

그러나 당신이 경비없이 그것을 만들면 마침내 매우 긴 길을 얻을 수 있습니다.

1
Andrei Keino

importlib 패키지 대신 imp을 사용하는 간단한 솔루션 (파이썬 2.7에서도 테스트되었지만 Python 3에서도 작동 함) :

import importlib

dirname, basename = os.path.split(pyfilepath) # pyfilepath: '/my/path/mymodule.py'
sys.path.append(dirname) # only directories should be added to PYTHONPATH
module_name = os.path.splitext(basename)[0] # '/my/path/mymodule.py' --> 'mymodule'
module = importlib.import_module(module_name) # name space of defined module (otherwise we would literally look for "module_name")

이제 다음과 같이 가져온 모듈의 네임 스페이스를 직접 사용할 수 있습니다.

a = module.myvar
b = module.myfunc(a)

이 솔루션의 장점은 코드에서 사용하기 위해 가져올 모듈의 실제 이름을 알 필요조차 없습니다입니다. 예 : 모듈의 경로가 구성 가능한 인수 인 경우.

1
Ataxias

이 목록을 답변 목록에 추가하면 효과가있는 것을 찾을 수 없었습니다. 이렇게하면 3.4에서 컴파일 된 (pyd) 파이썬 모듈을 가져올 수 있습니다 :

import sys
import importlib.machinery

def load_module(name, filename):
    # If the Loader finds the module name in this list it will use
    # module_name.__file__ instead so we need to delete it here
    if name in sys.modules:
        del sys.modules[name]
    loader = importlib.machinery.ExtensionFileLoader(name, filename)
    module = loader.load_module()
    locals()[name] = module
    globals()[name] = module

load_module('something', r'C:\Path\To\something.pyd')
something.do_something()
0
David

이 답변은 Sebastian Rittau의 답변에 대한 보충 설명입니다. "모듈 이름이 없으면 어떻게 될까요?" 이것은 파일 이름이 주어진 파이썬 모듈 이름을 얻는 빠르고 더러운 방법입니다. __init__.py 파일이없는 디렉토리를 찾은 다음 다시 파일 이름으로 바꿀 때까지 트리를 따라갑니다. Python 3.4 이상 (pathlib 사용)은 Py2 사용자가 "imp"또는 상대적인 가져 오기를 수행하는 다른 방법을 사용할 수 있기 때문에 의미가 있습니다.

import pathlib

def likely_python_module(filename):
    '''
    Given a filename or Path, return the "likely" python module name.  That is, iterate
    the parent directories until it doesn't contain an __init__.py file.

    :rtype: str
    '''
    p = pathlib.Path(filename).resolve()
    paths = []
    if p.name != '__init__.py':
        paths.append(p.stem)
    while True:
        p = p.parent
        if not p:
            break
        if not p.is_dir():
            break

        inits = [f for f in p.iterdir() if f.name == '__init__.py']
        if not inits:
            break

        paths.append(p.stem)

    return '.'.join(reversed(paths))

개선 할 가능성은 분명히 있습니다. 선택적인 __init__.py 파일은 다른 변경을 필요로 할 수도 있지만 일반적으로 __init__.py를 사용하면이 방법이 유용합니다.