programing

풀 패스를 지정하면 모듈을 동적으로 Import하려면 어떻게 해야 합니까?

showcode 2023. 4. 15. 09:39
반응형

풀 패스를 지정하면 모듈을 동적으로 Import하려면 어떻게 해야 합니까?

Python 모듈을 풀 패스로 로드하려면 어떻게 해야 합니까?

이 파일은 사용자가 액세스 권한을 가진 파일시스템 내 어디에나 존재할 수 있습니다.


다음 항목도 참조하십시오. 이름을 문자열로 지정한 모듈을 Import하려면 어떻게 해야 합니까?

Python 3.5+의 경우 (docs):

import importlib.util
import sys
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
sys.modules["module.name"] = foo
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 도 참조해 주세요.

sys.path에 경로를 추가하면(imp를 사용하는 것보다) 단일 패키지에서 여러 모듈을 Import할 때 작업이 간소화된다는 장점이 있습니다.예를 들어 다음과 같습니다.

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

모듈을 가져오려면 일시적으로 또는 영구적으로 환경 변수에 해당 디렉토리를 추가해야 합니다.

임시로

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

영구히

your에 행 .bashrc및(또는 (Linux 및 Excute)source ~/.bashrc의 : ( )

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

크레디트/출처: saarrr, 다른 스택 Exchange 질문

최상위 모듈이 파일이 아니라 __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의 상대 Import를 최상위 수준 모듈 이름(이 경우 mymodule)에 바인드하려고 합니다.그러나 "mymodule"이 아직 로드되지 않았기 때문에 "SystemError: 부모 모듈 'mymodule'이 로드되지 않았습니다, 상대적인 Import를 수행할 수 없습니다"라는 오류가 나타납니다.따라서 로드하기 전에 이름을 바인딩해야 합니다.그 이유는 상대 Import 시스템의 기본적인 불변성 때문입니다.「 sys . modules [ ' spam ' ]및 sys . modules [ ' spam ' spam ]가 있는 경우, 불변성 홀딩입니다.foo'](위의 Import 후와 마찬가지로 후자는 여기서 설명한 바와 같이 전자의 foo 속성으로 표시되어야 합니다.

컨피규레이션파일을 특별히 Import 하고 싶지 않은 것 같습니다(부작용이 많고 복잡성이 증가합니다).이 네임스페이스만 실행하고 결과 네임스페이스에 액세스 할 수 있습니다.표준 라이브러리는 runpy.run_path 형식으로 API를 제공합니다.

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

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

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

지저분하지만, 효과가 있어요.

configfile = '~/config.py'

import os
import sys

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

import config

@SebastianRittau의 훌륭한 답변(Python > 3.4의 경우)을 약간 수정했습니다.이것에 의해, 다음의 대신에 임의의 확장자를 가지는 파일을 모듈로서 로드할 수 있습니다.

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)

명시적인 경로 부호화의 장점은 기계가 확장자에서 파일 유형을 알아내려 하지 않는다는 것입니다.즉, 다음과 같은 것을 로드할 수 있습니다..txt " "로 할 수 .spec_from_file_location하지 않고 할 수 있습니다..txt는 에 없습니다.

이를 바탕으로 구현하고 @SamGrondahl의 유틸리티 라이브러리인 haggis수정했습니다.이 함수는 라고 불립니다.로드 시 모듈 네임스페이스에 변수를 삽입하는 기능 등 몇 가지 깔끔한 트릭을 추가합니다.

를 사용할 수 있습니다.

load_source(module_name, path_to_file)

메서드를 지정합니다.

로드 또는 Import를 의미합니까?

은 할 수 있어요.sys.pathlist를 .를를들,, 음음음음음음음음음 음음음음음음음음

/foo/bar.py

다음과 같은 작업을 할 수 있습니다.

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

여기 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())

시험해 봤어요.보기 흉할 수도 있지만, 지금까지 모든 버전에서 작동하는 것은 이것뿐입니다.

, 하다, 하다, 하다, 하다를 사용해서 할 수 있어요.__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')

같은 프로젝트에 다른 디렉토리 수단이 있는 경우, 이하의 방법으로 해결할 수 있습니다.

★★★★★★utils.pysrc/main/util/

import sys
sys.path.append('./')

import src.main.util.utils
#or
from src.main.util.utils import json_converter # json_converter is example method

Sebastian Ritau의 답변에 추가:적어도 CPython경우 pydoc이 있으며, 공식적으로 선언되지는 않았지만 파일을 가져오는 것은 다음과 같습니다.

from pydoc import importfile
module = importfile('/path/to/module.py')

PS. 완전성을 위해 현재 구현에 대한 언급이 있습니다.pydoc.py. xkcd 1987의 맥락에서는 이 구현이 21436호에서 언급된 구현 중 어느 것도 사용하지 않는다는 것을 기쁘게 생각합니다.

지정된 모듈을 로딩할 수 있다고 생각합니다.경로에서 모듈 이름을 분리해야 합니다. 예를 들어 로드하려면/home/mypath/mymodule.py하다

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

하지만 그렇게 하면 일이 끝날 거야

.pkgutilmodule(특히 메서드)을 사용하여 현재 디렉토리의 패키지 목록을 가져옵니다.거기서부터는, 이 머신을 사용할 수 있습니다.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!

여기에 특화된 패키지가 있습니다.

from thesmuggler import smuggle

# À la `import weapons`
weapons = smuggle('weapons.py')

# À la `from contraband import drugs, alcohol`
drugs, alcohol = smuggle('drugs', 'alcohol', source='contraband.py')

# À la `from contraband import drugs as dope, alcohol as booze`
dope, booze = smuggle('drugs', 'alcohol', source='contraband.py')

Python 버전(Jython과 PyPy도 마찬가지)에 걸쳐 테스트되고 있습니다만, 프로젝트의 규모에 따라서는 과잉인 경우가 있습니다.

Python 모듈 테스트를 만듭니다.py:

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

Python 모듈 test_check를 만듭니다.py:

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

모듈에서 Import한 모듈을 Import할 수 있습니다.

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에서 사용되지 않는 모듈을 사용하는 것으로 보입니다.왜 그런지는 모르겠지만, 프로그램 안에서 하는 것 같아요.커맨드 라인에서는 크리스의 솔루션이 동작하고 있었지만, 프로그램 내부에서는 동작하고 있지 않았습니다.

를 that that that that that that that that that that that that that 를 사용한 패키지를 .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/

특정 파일 이름에서 모듈을 Import하려면 일시적으로 경로를 확장하여 최종 블록 참조로 시스템 경로를 복원합니다.

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

를사 using using using importlibimp(Python 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")

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

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

솔루션의 장점은 코드로 사용하기 위해 Import할 모듈의 실제 이름을 알 필요도 없다는 것입니다.이는 모듈의 경로가 구성 가능한 인수인 경우 등에 유용합니다.

및 기능을 작성했습니다.importlib 모듈, 모듈:

  • 양쪽 모듈을 서브 모듈로 Import하여 모듈의 내용을 부모 모듈(또는 부모 모듈이 없는 경우 글로벌)로 Import할 수 있습니다.
  • 파일 이름에 마침표 문자가 포함된 모듈을 가져올 수 있습니다.
  • 임의의 확장자를 가진 모듈을 Import할 수 있습니다.
  • 기본적으로 확장자가 없는 파일 이름 대신 독립 실행형 이름을 하위 모듈에 사용할 수 있습니다.
  • Import에 하지 않고 할 수 .sys.path아니면 검색 경로 저장 저장소에서또는 검색 경로 스토리지에서 사용할 수 있습니다.

디렉토리 구조의 예를 다음에 나타냅니다.

<root>
 |
 +- test.py
 |
 +- testlib.py
 |
 +- /std1
 |   |
 |   +- testlib.std1.py
 |
 +- /std2
 |   |
 |   +- testlib.std2.py
 |
 +- /std3
     |
     +- testlib.std3.py

포함 종속성 및 순서:

test.py
  -> testlib.py
    -> testlib.std1.py
      -> testlib.std2.py
    -> testlib.std3.py

구현:

최신 변경 스토어: https://sourceforge.net/p/tacklelib/tacklelib/HEAD/tree/trunk/python/tacklelib/tacklelib.py

test.py:

import os, sys, inspect, copy

SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("test::SOURCE_FILE: ", SOURCE_FILE)

# portable import to the global space
sys.path.append(TACKLELIB_ROOT) # TACKLELIB_ROOT - path to the library directory
import tacklelib as tkl

tkl.tkl_init(tkl)

# cleanup
del tkl # must be instead of `tkl = None`, otherwise the variable would be still persist
sys.path.pop()

tkl_import_module(SOURCE_DIR, 'testlib.py')

print(globals().keys())

testlib.base_test()
testlib.testlib_std1.std1_test()
testlib.testlib_std1.testlib_std2.std2_test()
#testlib.testlib.std3.std3_test()                             # does not reachable directly ...
getattr(globals()['testlib'], 'testlib.std3').std3_test()     # ... but reachable through the `globals` + `getattr`

tkl_import_module(SOURCE_DIR, 'testlib.py', '.')

print(globals().keys())

base_test()
testlib_std1.std1_test()
testlib_std1.testlib_std2.std2_test()
#testlib.std3.std3_test()                                     # does not reachable directly ...
globals()['testlib.std3'].std3_test()                         # ... but reachable through the `globals` + `getattr`

testlib.py:

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("1 testlib::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/std1', 'testlib.std1.py', 'testlib_std1')

# SOURCE_DIR is restored here
print("2 testlib::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/std3', 'testlib.std3.py')

print("3 testlib::SOURCE_FILE: ", SOURCE_FILE)

def base_test():
  print('base_test')

testlib.std1.py:

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std1::SOURCE_FILE: ", SOURCE_FILE)

tkl_import_module(SOURCE_DIR + '/../std2', 'testlib.std2.py', 'testlib_std2')

def std1_test():
  print('std1_test')

testlib.std2.py:

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std2::SOURCE_FILE: ", SOURCE_FILE)

def std2_test():
  print('std2_test')

testlib.std3.py:

# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)

print("testlib.std3::SOURCE_FILE: ", SOURCE_FILE)

def std3_test():
  print('std3_test')

출력(3.7.4):):

test::SOURCE_FILE:  <root>/test01/test.py
import : <root>/test01/testlib.py as testlib -> []
1 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std1/testlib.std1.py as testlib_std1 -> ['testlib']
import : <root>/test01/std1/../std2/testlib.std2.py as testlib_std2 -> ['testlib', 'testlib_std1']
testlib.std2::SOURCE_FILE:  <root>/test01/std1/../std2/testlib.std2.py
2 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std3/testlib.std3.py as testlib.std3 -> ['testlib']
testlib.std3::SOURCE_FILE:  <root>/test01/std3/testlib.std3.py
3 testlib::SOURCE_FILE:  <root>/test01/testlib.py
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'os', 'sys', 'inspect', 'copy', 'SOURCE_FILE', 'SOURCE_DIR', 'TackleGlobalImportModuleState', 'tkl_membercopy', 'tkl_merge_module', 'tkl_get_parent_imported_module_state', 'tkl_declare_global', 'tkl_import_module', 'TackleSourceModuleState', 'tkl_source_module', 'TackleLocalImportModuleState', 'testlib'])
base_test
std1_test
std2_test
std3_test
import : <root>/test01/testlib.py as . -> []
1 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std1/testlib.std1.py as testlib_std1 -> ['testlib']
import : <root>/test01/std1/../std2/testlib.std2.py as testlib_std2 -> ['testlib', 'testlib_std1']
testlib.std2::SOURCE_FILE:  <root>/test01/std1/../std2/testlib.std2.py
2 testlib::SOURCE_FILE:  <root>/test01/testlib.py
import : <root>/test01/std3/testlib.std3.py as testlib.std3 -> ['testlib']
testlib.std3::SOURCE_FILE:  <root>/test01/std3/testlib.std3.py
3 testlib::SOURCE_FILE:  <root>/test01/testlib.py
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'os', 'sys', 'inspect', 'copy', 'SOURCE_FILE', 'SOURCE_DIR', 'TackleGlobalImportModuleState', 'tkl_membercopy', 'tkl_merge_module', 'tkl_get_parent_imported_module_state', 'tkl_declare_global', 'tkl_import_module', 'TackleSourceModuleState', 'tkl_source_module', 'TackleLocalImportModuleState', 'testlib', 'testlib_std1', 'testlib.std3', 'base_test'])
base_test
std1_test
std2_test
std3_test

Tested in Python Python에서 테스트 완료3.7.4,3.2.5,2.7.16

장점:

  • 양쪽 모듈을 서브모듈로 Import할 수 있으며 모듈의 콘텐츠를 부모 모듈(또는 부모 모듈이 없는 경우 글로벌)로 Import할 수 있습니다.
  • 파일 이름에 마침표가 있는 모듈을 가져올 수 있습니다.
  • 임의의 확장 모듈에서 임의의 확장 모듈을 Import할 수 있습니다.
  • 기본(예: 본, 기, example 니 다 수 있 습 름 독 을 ( 신 용 can use (이 할 사 장형 by행름모testlib.std.py as ~하듯이testlib,testlib.blabla.py as ~하듯이testlib_blabla그래서요.등 ) 。
  • 하지 않습니다.sys.path또는 검색 경로 스토리지에서 사용할 수 있습니다.
  • 음음음 / global to복복 like like like like like like like like like like like like like like like like 등의 글로벌 .SOURCE_FILE ★★★★★★★★★★★★★★★★★」SOURCE_DIRtkl_import_module.
  • [[3.4.x 네임스페이스를 네임스페이스에 시킬 수 .tkl_import_module 「」(예: 「」)named->local->named ★★★★★★★★★★★★★★★★★」local->named->local등 ) 。
  • [[3.4.x 이상]함수/되어 있는 에서 Import를 Import된 모든 수 .tkl_import_module (을)tkl_declare_global★★★★★★★★★★★★★★★★★★」

단점:

  • 수입하다
    • 열거 및 서브클래스를 무시합니다.
    • 각 유형을 배타적으로 복사해야 하므로 기본 제공 기능을 무시합니다.
    • 3가지로 복사할 수 없는 클래스는 무시하십시오.
    • 패키지화된 모든 모듈을 포함한 내장 모듈의 복사를 방지합니다.
  • [[3.3.x[ lower 를 선언해야 .tkl_import_module 모든 tkl_import_module 복제코드 복제)

업데이트 1,2 (용)3.4.x★★★★★★★★★★★★★★★★★★:

3.4에서는 Python 3.4를 선언하는 할 수 .tkl_import_module에서 "Declaration"을 선언합니다.tkl_import_module이 함수는 모든 자모듈에 1회의 콜로 주입됩니다(자기 전개 Import의 일종).

업데이트 3:

" " " 가 되었습니다.tkl_source_modulesourceImport하다

업데이트 4:

" " " 가 되었습니다.tkl_declare_global자모듈의 일부가 아니기 때문에 모듈글로벌 변수가 표시되지 않는 모든 자모듈에 모듈글로벌 변수를 자동으로 내보냅니다.

업데이트 5:

모든 함수가 태클립 라이브러리로 이동했습니다. 위의 링크를 참조하십시오.

이거면 될 것 같아

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)

런타임에 패키지 모듈 가져오기(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)

좋다고 하는 것은 아니지만, 완성도를 높이기 위해 Python 2와 Python 3 모두 사용할 수 있는 기능을 제안하고 싶습니다.

exec를 사용하면 글로벌스코프 또는 사전으로 제공되는 내부스코프에서 임의의 코드를 실행할 수 있습니다.

에 저장되어 "/path/to/module 「 」을 .foo()할 수 있습니다 , 하다, 하다, 하다, 하다.

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

이것에 의해, 동적으로 코드를 로드하는 것이 보다 명확하게 되어, 커스텀 빌트인을 제공하는 등, 한층 더 파워가 부여됩니다.

또한 키 대신 속성을 통해 액세스할 수 있는 것이 중요한 경우, 다음과 같은 액세스를 제공하는 글로벌용 커스텀 딕트 클래스를 설계할 수 있습니다.

class MyModuleClass(dict):
    def __getattr__(self, name):
        return self.__getitem__(name)

Linux 에서는 Python 스크립트가 위치한 디렉토리에 심볼릭링크를 추가하면 동작합니다.

예:

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

는 Python을 ./absolute/path/to/script/module.pyc 이 업데이트가 ./absolute/path/to/module/module.py.

그런 다음 mypythonscript 파일에 다음을 포함합니다.py:

from module import *

이를 통해 컴파일된(pyd) Python 모듈을 3.4로 Import할 수 있습니다.

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()

간단한 방법: 상대 경로로 파일을 Import하는 경우를 가정해 보겠습니다.//MyLibs/pyfunc.화이

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

하지만 경비원 없이 해내면 아주 먼 길을 갈 수 있어요.

pathlib만을 사용하는 두 가지 유틸리티 기능입니다.경로에서 모듈 이름을 유추합니다.

기본적으로는 폴더에서 모든 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

이 답변은 Sebastian Rittau가 "하지만 모듈 이름이 없으면 어떻게 합니까?"라는 코멘트에 대한 답변을 보충한 것입니다.이것은 파일명이 주어질 가능성이 높은 Python 모듈명을 취득하는 빠르고 더러운 방법입니다.--이것은, Python 모듈명이 없는 디렉토리를 찾을 때까지, 트리 위로 올라가기만 하면 됩니다.__init__.py이치노Python 3.4+(pathlib 사용)의 경우, Python 2 사용자는 "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))

선의의 、 optional there there 、 there there optional there there there 。__init__.py다른 할 수 있지만 에는 변경이 합니다.__init__.py일반적으로, 이것이 효과가 있습니다.

언급URL : https://stackoverflow.com/questions/67631/how-can-i-import-a-module-dynamically-given-the-full-path

반응형