programing

Python에서 상대적인 Import는 어떻게 해야 하나요?

newnotes 2023. 4. 10. 22:15
반응형

Python에서 상대적인 Import는 어떻게 해야 하나요?

다음의 디렉토리 구조를 상상해 주세요.

app/
   __init__.py
   sub1/
      __init__.py
      mod1.py
   sub2/
      __init__.py
      mod2.py

하고 mod1 Import하다에서 할 것이 mod2떻게게 해???

는 는 i i는노노 i i i i i.from ..sub2 import mod2수입하다

해 본 것은 「아, 아, 아...」이었다.sys.path방법은?끔한한 방법? ???


의 모든 것__init__.py 현재 있습니다.

되어 있기 때문에 이 sub2는 서브패키지 간에 공유되는 클래스입니다).sub1,subX등 ) 。

제가 찾고 있는 행동은 PEP 366에서 설명한 것과 같습니다(고맙습니다 John B).

문제는 인터프리터에 인수로서 mod1.py을 전달함으로써 모듈을 '_main__'로 실행하고 있다는 것입니다.

PEP 328부터:

상대 Import에서는 모듈의 __name_ 속성을 사용하여 패키지 계층에서 해당 모듈의 위치를 결정합니다.모듈 이름에 패키지 정보가 포함되어 있지 않은 경우(예를 들어 '_main__'로 설정되어 있는 경우), 파일 시스템의 실제 위치에 관계없이 모듈이 최상위 모듈인 것처럼 상대 Import가 해결됩니다.

Python 2.6에서는 메인 모듈을 기준으로 모듈을 참조할 수 있는 기능이 추가되었습니다.PEP 366은 변경에 대해 설명합니다.

Nick Coghlan에 따르면 권장되는 대안은 -m 스위치를 사용하여 패키지 내에서 모듈을 실행하는 것입니다.

다음과 같은 솔루션을 이용할 수 있습니다.

나는 상대적인 수입을 한다.from ..sub2 import mod2나서 제가 리고,,를 약면면면면면면면면면면면면면면면면면면면면면면면mod1.py '아까보다'의 부모 합니다.app - m를 python - m으로 사용하여 합니다.python -m app.sub1.mod1.

이 가 「」를 입니다.__name__모듈의 속성입니다.되고 있는 는, 「」를 참조해 .__name__로 설정되어 있다.__main__패키지 구조에 대한 정보는 포함되어 있지 않습니다.은 리고, 래 the about about about about about about 에 대해 을 한다relative import in non-package

따라서 -m 스위치를 사용하여 패키지 구조 정보를 python에 제공하므로 python은 이를 통해 상대적인 Import를 성공적으로 해결할 수 있습니다.

저는 상대적인 수입을 하면서 이 문제를 여러 번 겪었습니다.그리고 앞의 답을 다 읽고 나서도, 모든 파일에 보일러 플레이트 코드를 넣지 않고, 깔끔하게 해결할 수 있는 방법을 찾을 수 없었습니다.(일부 댓글은 @ncoghlan과 @XiongChiamiov 덕분에 큰 도움이 되었습니다.)

PEP를 거치는 것은 정말 재미가 없기 때문에, 이것은 상대적인 수입 문제로 싸우고 있는 사람에게 도움이 되기를 바랍니다.

main.py
setup.py
app/ ->
    __init__.py
    package_a/ ->
       __init__.py
       module_a.py
    package_b/ ->
       __init__.py
       module_b.py
  1. 이 뛰어요.python main.py.
  2. main.py 하다, 하다, 하다, 하다.import app.package_a.module_a
  3. module_a.pyimport app.package_b.module_b

2 을 사용할 수 : 는 2 、 3 、 을 3 。from app.package_a import module_a

은 당신이 한 것이다.appPYTONPATH: PYTONPATH 。 main.py어디든지 있을 수 있어요

쓰세요.setup.py앱 시스템의 폴더에 복사( 방법, "앱 와 서브패키지를 복사(설치)하는 방법 등이 .main.py타겟을 지정합니다.

"Guido는 패키지 내에서 실행 중인 스크립트를 안티패턴으로 본다"(거부된 PEP-3122)

Stack Overflow의 관련 게시물을 읽고 "더 좋은 방법이 있을 거야!"라고 혼잣말을 하며 해결책을 찾기 위해 많은 시간을 보냈습니다.없는 것 같네요.

이 문제는 100% 해결되었습니다.

  • //
    • main.py
  • ★★★★★★★/ ★★★★★★★★★★
    • local_settings.화이

app/main에서 settings/local_setting.py를 가져옵니다.py:

main.py:

import sys
sys.path.insert(0, "../settings")


try:
    from local_settings import *
except ImportError:
    print('No Import')

예를 들어 nosklo의 답변 설명:

: 항목:__init__.py파일이 비어 있습니다.

main.py
app/ ->
    __init__.py
    package_a/ ->
       __init__.py
       fun_a.py
    package_b/ ->
       __init__.py
       fun_b.py

app/fun_a.py

def print_a():
    print 'This is a function in dir package_a'

app/fun_b.py

from app.package_a.fun_a import print_a
def print_b():
    print 'This is a function in dir package_b'
    print 'going to call a function in dir package_a'
    print '-'*30
    print_a()

main.py

from app.package_b import fun_b
fun_b.print_b()

<고객명>을python main.py★★★★

This is a function in dir package_b
going to call a function in dir package_a
------------------------------
This is a function in dir package_a
  • py의 : 메인py:from app.package_b import fun_b
  • do fun_b.py does fun_b.py가 되다from app.package_a.fun_a import print_a

in folder(폴더에 파일)을 넣어주세요.package_bpackage_a?? ? 、 ? 、 ?、 ? 、 ? 、 ? 、 ?★★★★★★★★★★★★★★★★★?

용도:

def import_path(fullpath):
    """ 
    Import a file with full path specification. Allows one to
    import from anywhere, something __import__ does not do. 
    """
    path, filename = os.path.split(fullpath)
    filename, ext = os.path.splitext(filename)
    sys.path.append(path)
    module = __import__(filename)
    reload(module) # Might be out of date
    del sys.path[-1]
    return module

이 스니펫을 사용하여 경로에서 모듈을 Import합니다.

이것은 불행히도 sys.path 해킹이지만 꽤 잘 작동합니다.

다른 레이어에서 이 문제가 발생했습니다.이미 지정된 이름의 모듈을 사용하고 있었는데 잘못된 모듈이었습니다.

제가 하고 싶었던 것은 다음과 같습니다(모듈3에서 작업한 모듈).

mymodule\
   __init__.py
   mymodule1\
      __init__.py
      mymodule1_1
   mymodule2\
      __init__.py
      mymodule2_1


import mymodule.mymodule1.mymodule1_1  

mymodule은 이미 설치되었지만 설치에는 mymodule1이 없습니다.

설치되어 있는 모듈에서 Import하려고 했기 때문에 ImportError가 표시됩니다.

sys.path.append를 시도했지만 소용이 없었어요.동작한 것은 sys.path.insert 입니다.

if __name__ == '__main__':
    sys.path.insert(0, '../..')

정말 대단한 해킹이지만, 모든 게 잘 풀렸어요!따라서 다른 경로를 덮어쓰려면 sys.path.insert(0, pathname)를 사용하여 작동해야 합니다.이것은 저에게 매우 곤란한 문제였습니다.많은 사람들이 sys.path에 "append" 함수를 사용하라고 말합니다만, 이미 모듈이 정의되어 있는 경우는 동작하지 않습니다(매우 이상한 동작입니다).

제가 참고할 수 있도록 이 부분을 여기에 두겠습니다. Python 코드가 것은 , 하고 있는 에, 그 를 Python의 에 넣고 은 Python 코드입니다.scripts디렉토리로 이동합니다.

import os.path
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))

EvgeniSergeev가 OP에 대한 코멘트에서 말한 것처럼 코드 Import는.py다음 파일을 사용하여 임의 위치에 보관합니다.

import imp

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

이것은 이 SO 답변에서 가져온 것입니다.

http://docs.python.org/whatsnew/2.5.html#pep-328-absolute-and-relative-imports 를 참조해 주세요.할 수 있다

from .mod1 import stuff

Python 문서에서

2.에서는 Import를 사용하여 Import할 수 .from __future__ import absolute_import 은 향후7)에서이 될 것입니다.Import Python 2.7의 Import입니다.되어 있는 , 「Import」는 「Import」를 해 주세요.import string는 항상 표준 라이브러리의 버전을 검색합니다.한 좋기 에 Import를 이 좋습니다.from pkg import string의 코드로

를 ' 낫다'에 .PYTHONPATH

export PYTHONPATH="${PYTHONPATH}:/path/to/your/module/"

실행 시 현재 디렉토리를 PATH에 추가하는 방법은 다음과 같습니다.

import pathlib   
import sys
sys.path.append(pathlib.Path(__file__).parent.resolve())
import file_to_import  # the actual intended import

, 이 질문에서는 을 사용합니다.pathlibos.path.

"PYthonPATH" 환경 변수를 맨 위 폴더로 설정하는 것이 더 쉬웠습니다.

bash$ export PYTHONPATH=/PATH/TO/APP

그 후, 다음과 같이 입력합니다.

import sub1.func1
# ...more imports

물론 PYTONPATH는 '글로벌'이지만, 저는 아직 문제가 되지 않았습니다.

존 B가 말한 것 보다 더 중요한 것은__package__는 도움이입니다.변수는 도움이 될 입니다.__main__ 때는 것 같아요.하지만 제가 테스트할 수 있는 한, 완전히 제대로 작동하지 않습니다.

저는 같은 문제를 안고 있으며 PEP 328과 PEP 366 모두 문제를 완전히 해결하지 못하고 있습니다.둘 다 오늘 중으로 패키지 헤드를 포함할 필요가 있기 때문입니다.sys.path내가 이해한 바로는.

이 메서드는 경로를 쿼리하고 자동으로 채웁니다.

import os
import inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
os.sys.path.insert(1, parentdir)
# print("currentdir = ", currentdir)
# print("parentdir=", parentdir)

대단한 토론이네요!

저는 Python의 비교적 초보자(다년간의 프로그래밍 경험으로 Perl을 싫어함)이며 Apache 셋업의 다크 아트에 관해서는 비교적 문외한이지만, 집에서 작은 실험 프로젝트를 실행하기 위해 무엇이 필요한지 알고 있습니다.

여기 그 상황이 어떤 것 같은지에 대한 나의 요약이 있다.

m 'module' 접근 방식을 사용할 경우 다음 작업을 수행해야 합니다.

  1. 모두 함께 점 찍는다;
  2. 상위 폴더에서 실행;
  3. .py'를 잃는다;
  4. 만들다__init__.py모든 서브폴더에 파일을 저장합니다.

스크립트 디렉토리에 에일리어스를 붙여 /dirAlias/cgi_script.py로 직접 스크립트를 실행하는 CGI 환경에서는 어떻게 동작합니까?

sys.path 수정이 해킹인 이유는 무엇입니까?Python 문서 페이지에는 다음과 같이 기술되어 있습니다. "프로그램은 자신의 목적을 위해 이 목록을 자유롭게 수정할 수 있습니다."잘 되면 되는 거죠?Accounts의 bean 카운터는 어떻게 동작하는지는 신경 쓰지 않습니다.

한 단계 더 올라가 'modules' 디렉토리로 내려가면 됩니다.

.../py
      /cgi
      /build
      /modules

따라서 CGI 월드 또는 서버 월드에서 '모듈'을 가져올 수 있습니다.

-m하지만 저는 다음 공간에서 modules 어 어 、 음 、 음 、 음음음( ( CGI ) 。

  1. XX_pathsetup.py/path/to/python/Lib 디렉토리(또는 기본 sys.path 목록 내의 다른 디렉토리)에 있습니다.'XX'는 파일의 규칙에 따라 경로를 설정할 의도를 선언하는 식별자입니다.

  2. 설정내의 할수는, 「modules」의 「modules」의 「import」를 실시합니다.import XX_pathsetup.py.

다음은 매우 간단한 XX_pathsetup.py 파일입니다.

import sys, os
pypath = sys.path[0].rsplit(os.sep, 1)[0]
sys.path.insert(0, pypath + os.sep + 'modules')

해킹이 아니야, IMHO.Python 'Lib' 디렉토리에 넣을 작은 파일과 경로 검색 순서를 수정할 의도를 선언하는 Import 문입니다.

언급URL : https://stackoverflow.com/questions/72852/how-can-i-do-relative-imports-in-python

반응형