programing

.py 확장자없이 파이썬 모듈 가져 오기

nasanasas 2020. 12. 5. 09:53
반응형

.py 확장자없이 파이썬 모듈 가져 오기


foobar라는 파일이 있습니다 (.py 확장자 없음). 같은 디렉토리에 가져 오기를 시도하는 또 다른 파이썬 파일이 있습니다.

import foobar

그러나 이것은 파일 이름을 foobar.py로 변경하는 경우에만 작동합니다. .py 확장자가없는 파이썬 모듈을 가져올 수 있습니까?

업데이트 : 독립 실행 형 스크립트로도 사용하기 때문에 파일에 확장자가 없으며 .py 확장자를 입력하여 실행하고 싶지 않습니다.

Update2 : 아래에 언급 된 심볼릭 링크 솔루션으로 이동합니다.


imp.load_source( imp모듈에서) 함수 를 사용하여 주어진 파일 시스템 경로에서 동적으로 모듈을로드 할 수 있습니다 .

foobar = imp.load_source('foobar', '/path/to/foobar')

SO 토론 에서는 몇 가지 흥미로운 옵션도 보여줍니다.


다른 사람들이 언급했듯이 imp.load_source를 사용할 수 있지만 코드를 읽기가 더 어려워집니다. 런타임까지 이름이나 경로를 알 수없는 모듈을 가져와야하는 경우에만 권장합니다.

.py 확장자를 사용하지 않으려는 이유는 무엇입니까? .py 확장자를 사용하지 않으려는 가장 일반적인 경우는 python 스크립트도 실행 파일로 실행되지만 다른 모듈에서 가져올 수 있기를 원하기 때문입니다. 이 경우 유사한 이름의 .py 파일로 기능을 이동 한 다음 foobar래퍼 로 사용하는 것이 유용 할 수 있습니다 .


imp.load_source(module_name, path)해야하거나 imp.load_module(module_name, file_handle, ...)파일 핸들이있는 경우 더 자세한 경로를 수행 할 수 있습니다.


다음은 Python 3.4 이상을위한 솔루션입니다.

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

spec = spec_from_loader("foobar", SourceFileLoader("foobar", "/path/to/foobar"))
foobar = module_from_spec(spec)
spec.loader.exec_module(foobar)

를 사용 spec_from_loader하고 명시 적으로 지정 SourceFileLoader하면 기계 가 확장자에서 파일 유형을 알아 내지 않고 파일을 소스로로드 하도록 강제합니다 . 즉,에 나열되어 있지 않더라도 파일을로드 할 수 있습니다 importlib.machinery.SOURCE_SUFFIXES.

처음로드 한 후에도 이름으로 파일을 계속 가져 오려면 다음 위치에 모듈을 추가하십시오 sys.modules.

sys.modules['foobar'] = foobar

패키지 관리자 (deb 또는 유사)로 스크립트를 설치하는 경우 또 다른 옵션은 setuptools를 사용하는 것입니다.

"... 스크립트의 파일 이름이 Windows 및 POSIX 플랫폼 모두에서 로컬 규칙과 일치하도록하는 쉬운 방법은 없습니다. 다른 경우에는 실제"main "이 다음과 같은 경우"main "스크립트에 대해 별도의 파일을 만들어야하는 경우가 많습니다. 모듈 어딘가에있는 기능 ... setuptools는 올바른 확장자를 가진 스크립트를 자동으로 생성하여 이러한 모든 문제를 해결하며 Windows에서는 .exe 파일도 생성합니다 ... "

https://pythonhosted.org/setuptools/setuptools.html#automatic-script-creation


importlib 도우미 기능

여기 imp에 언급 된 내용을 기반으로 하여을 (를) 대체 할 편리하고 바로 사용할 수있는 도우미가 있습니다 . https://stackoverflow.com/a/43602645/895245

main.py

#!/usr/bin/env python3

import os
import importlib

def import_path(path):
    module_name = os.path.basename(path).replace('-', '_')
    spec = importlib.util.spec_from_loader(
        module_name,
        importlib.machinery.SourceFileLoader(module_name, path)
    )
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    sys.modules[module_name] = module
    return module

notmain = import_path('not-main')
print(notmain)
print(notmain.x)

메인이 아닌

x = 1

운영:

python3 main.py

산출:

<module 'not_main' from 'not-main'>
1

I replace - with _ because my importable Python executables without extension have hyphens. This is not mandatory, but produces better module names.

This pattern is also mentioned in the docs at: https://docs.python.org/3.7/library/importlib.html#importing-a-source-file-directly

I ended up moving to it because after updating to Python 3.7, import imp prints:

DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses

and I don't know how to turn that off.

Tested in Python 3.7.3.

참고URL : https://stackoverflow.com/questions/2601047/import-a-python-module-without-the-py-extension

반응형