[python] Python 검색 경로를 다른 소스로 확장

기존 코드 기반이 상당히 큰 프로젝트에 방금 참여했습니다. 우리는 리눅스에서 개발하고 IDE를 사용하지 않습니다. 명령 줄을 통해 실행합니다. 프로젝트 모듈을 실행할 때 파이썬이 올바른 경로를 검색하도록하는 방법을 알아 내려고합니다. 예를 들어 다음과 같이 실행할 때 :

python someprojectfile.py

나는 얻다

ImportError: no module named core.'somemodule'

나는 그것이 경로에 문제가 있다고 가정하기 위해 모든 가져 오기에 대해 이것을 얻습니다.

TLDR :

~/codez/project/import 문 중에 Python이 * .py 파일 을 검색 하고 모든 파일과 폴더 를 검색하도록하려면 어떻게해야합니까?



답변

이를 수행하는 몇 가지 가능한 방법이 있습니다.

  • PYTHONPATH가져온 모듈을 검색 하려면 환경 변수 를 콜론으로 구분 된 디렉토리 목록으로 설정하십시오 .
  • 프로그램에서를 사용 sys.path.append('/path/to/search')하여 Python이 가져온 모듈을 검색 할 디렉토리 이름을 추가합니다. sys.path파이썬이 모듈을 가져 오라는 요청을받을 때마다 검색하는 디렉토리 목록 일 뿐이며 필요에 따라 변경할 수 있습니다 (표준 디렉토리를 제거하는 것은 권장하지 않습니다!). 환경 변수에 넣은 모든 디렉토리 PYTHONPATHsys.pathPython이 시작될 때 삽입됩니다 .
  • site.addsitedir에 디렉토리를 추가하는 데 사용 합니다 sys.path. 이것과 단순한 추가의 차이점은를 사용할 때 해당 디렉토리 내 addsitedir에서 .pth파일을 찾고 파일 sys.path의 내용에 따라 추가 디렉토리를 추가하는 데 사용할 수 있다는 것 입니다. 자세한 내용은 설명서를 참조하십시오.

이 중 사용하려는 것은 상황에 따라 다릅니다. 당신이 다른 사용자에게 프로젝트를 배포 할 때 파이썬 코드 파일이 자동으로 (즉, 패키지가 보통에 설치되어 파이썬의 수입에 의해 감지됩니다, 그들은 일반적으로 같은 방식으로 설치할 것을 기억 site-packages디렉토리)와 함께, 그래서 당신이 경우 엉망 sys.path코드에 , 이는 불필요 할 수 있으며 해당 코드가 다른 컴퓨터에서 실행될 때 악영향을 미칠 수도 있습니다. 개발을 위해 설정 PYTHONPATH이 일반적으로 가장 좋은 방법 이라고 추측합니다 .

그러나 자신의 컴퓨터에서 실행되는 것을 사용하는 경우 (또는 비표준 설정이있는 경우 (예 : 가끔 웹 앱 프레임 워크에서)) 다음과 같은 작업을 수행하는 것이 드물지 않습니다.

import sys
from os.path import dirname
sys.path.append(dirname(__file__))


답변

http://docs.python.org/tutorial/modules.html에서 파이썬 패키지에 대해 읽어야합니다 .

귀하의 예에서 실제로 ~/codez/project. __init__.pypython 디렉토리 의 파일 은 디렉토리를 네임 스페이스로 매핑합니다. 하위 디렉터리에 모두 __init__.py파일 이있는 경우 기본 디렉터리 만 PYTHONPATH. 예를 들면 :

PYTHONPATH = $ PYTHONPATH : $ HOME / adaifotis / project

David가 설명했듯이 PYTHONPATH 환경 변수를 테스트하는 것 외에도 다음과 같이 Python에서 테스트 할 수 있습니다.

$ python
>>> import project                      # should work if PYTHONPATH set
>>> import sys
>>> for line in sys.path: print line    # print current python path


답변

이 스레드가 조금 오래되었다는 것을 알고 있지만이 스레드의 핵심을 파악하는 데 시간이 좀 걸렸기 때문에 공유하고 싶었습니다.

내 프로젝트에서는 상위 디렉토리에 기본 스크립트가 있고 모듈을 구분하기 위해 모든 지원 모듈을 “모듈”이라는 하위 폴더에 넣었습니다. 내 기본 스크립트에서 다음과 같은 모듈을 가져옵니다 (report.py라는 모듈의 경우).

from modules.report import report, reportError

메인 스크립트를 호출하면 작동합니다. 그러나 각 모듈에 a main()를 포함하고 다음 과 같이 직접 호출 하여 각 모듈을 테스트하고 싶었습니다 .

python modules/report.py

이제 파이썬은 “모듈이라는 모듈”을 찾을 수 없다고 불평합니다. 여기서 핵심은 기본적으로 Python이 검색 경로에 스크립트 폴더를 포함하지만 CWD는 포함하지 않는다는 것입니다. 이 오류가 실제로 말하는 것은 “모듈 하위 폴더를 찾을 수 없습니다”입니다. 이는 report.py 모듈이있는 디렉토리에 “modules”하위 디렉토리가 없기 때문입니다.

이것에 대한 가장 좋은 해결책은 상단에 이것을 포함하여 Python 검색 경로에 CWD를 추가하는 것입니다.

import sys

sys.path.append(".")

이제 Python은 CWD (현재 디렉터리)를 검색하고 “modules”하위 폴더를 찾습니다. 모든 것이 정상입니다.


답변

나는 답을 찾기 위해이 질문을 읽었고 그들 중 어느 것도 좋아하지 않았습니다.

그래서 저는 빠르고 더러운 해결책을 썼습니다. sys.path 어딘가에 이것을 넣으면 folder(현재 작업 디렉토리에서) 또는 아래에 디렉토리가 추가 됩니다 abspath.

#using.py

import sys, os.path

def all_from(folder='', abspath=None):
    """add all dirs under `folder` to sys.path if any .py files are found.
    Use an abspath if you'd rather do it that way.

    Uses the current working directory as the location of using.py. 
    Keep in mind that os.walk goes *all the way* down the directory tree.
    With that, try not to use this on something too close to '/'

    """
    add = set(sys.path)
    if abspath is None:
        cwd = os.path.abspath(os.path.curdir)
        abspath = os.path.join(cwd, folder)
    for root, dirs, files in os.walk(abspath):
        for f in files:
            if f[-3:] in '.py':
                add.add(root)
                break
    for i in add: sys.path.append(i)

>>> import using, sys, pprint
>>> using.all_from('py') #if in ~, /home/user/py/
>>> pprint.pprint(sys.path)
[
#that was easy
]

그리고 나는 임의의 도구를위한 폴더를 가질 수 있고 그것들이 패키지 나 다른 것의 일부가되지 않고, 몇 줄의 코드로 그들 중 일부 (또는 전부)에 여전히 액세스 할 수 있기 때문에 그것을 좋아합니다.


답변

내가 찾는 가장 쉬운 방법은 “any_name.pth”파일을 만들어 “\ Lib \ site-packages”폴더에 넣는 것입니다. 파이썬이 설치된 모든 폴더를 찾아야합니다.

해당 파일에 가져올 모듈을 보관할 디렉토리 목록을 넣으십시오. 예를 들어, 해당 파일에 다음과 같은 라인을 만드십시오.

C : \ Users \ example … \ example

파이썬에서 이것을 실행하여 작동하는지 알 수 있습니다.

import sys
for line in sys: print line

가져올 수있는 다른 것들 중에서 디렉토리가 인쇄 된 것을 볼 수 있습니다. 이제 해당 디렉토리에있는 “mymodule.py”파일을 다음과 같이 쉽게 가져올 수 있습니다.

import mymodule

하위 폴더를 가져 오지 않습니다. 이를 위해 정의한 폴더의 모든 하위 폴더를 포함하는 .pth 파일을 만드는 파이썬 스크립트를 만드는 것을 상상할 수 있습니다. 아마도 시작할 때 실행하십시오.


답변

이전 질문에 대한 새로운 옵션입니다.
설치 fail2ban데비안 패키지를, 그것은 같은 외모에 설치할 하드 코딩 것 /usr/lib/python3/dist-packages/fail2ban경로하지 python3에 sys.path.


> python3
Python 3.7.3 (v3.7.3:ef4ec6ed12, Jun 25 2019, 18:51:50)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/usr/lib/python37.zip', '/usr/lib/python3.7', '/usr/lib/python3.7/lib-dynload', '/usr/lib/python3.7/site-packages']
>>>

따라서 복사하는 대신 라이브러리를 최신 버전에 연결했습니다.
원래 앱에 대한 향후 업데이트는 연결된 버전에도 자동으로 적용됩니다.

 if [ -d /usr/lib/python3/dist-packages/fail2ban ]
   then
      for d in /usr/lib/python3.*
      do
         [ -d ${d}/fail2ban ] || \
            ln -vs /usr/lib/python3/dist-packages/fail2ban ${d}/
      done
   fi


답변