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


106

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

python someprojectfile.py

나는 얻다

ImportError: no module named core.'somemodule'

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

TLDR :

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

답변:


171

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

  • 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__))

그래서 내가 15 개의 하위 디렉토리를 말했으면 각각을 개별적으로 추가해야할까요?
themaestro

PYTHONPATH를 변경하는 명령 줄 인수의 예를 제공 할 수 있습니까?
themaestro

3
설정하려면 PYTHONPATH: in .bashrc또는 쉘에서 사용하는 시작 파일 (Bash가 아닌 경우)을 작성하십시오 export PYTHONPATH=$PYTHONPATH:$HOME/codez/project. 그러나 많은 하위 디렉토리가 있으면 .pth파일을 만들고 site.addsitedir. sitecustomize함수를 호출 할 수있는 모듈 을 만들 수 있습니다 . 에서 퍼팅 시도 ~/.local/lib/python2.6/sitecustomize.py가 잘하면 자동으로 가져됩니다 있도록 (파이썬 버전을 대체).
David Z

.bashrc 파일에 다음을 넣었는데 여전히 해당 가져 오기에 운이 없습니다. 어떤 아이디어? 어쨌든 .pth 파일을 어떻게 만들 수 있습니까? export PYTHONPATH = $ PYTHONPATH : $ HOME / adaifotis / codez / export PYTHONPATH = $ PYTHONPATH : $ HOME / adaifotis / codez / project export PYTHONPATH = $ PYTHONPATH : $ HOME / adaifotis / codez / project / core export PYTHONPATH = $ PYTHONPATH : $ HOME / adaifotis / codez / 프로젝트 / 프록시 수출 PYTHONPATH = $ PYTHONPATH : $ HOME / adaifotis / codez / 프로젝트 / conf의
themaestro

터미널을 열고 echo $PYTHONPATH. 환경 변수가 올바르게 설정된 경우 콜론으로 구분 된 디렉토리 목록이 표시됩니다. .pth파일에 대한 정보 site는 내 대답에서 링크 한 모듈에 대한 문서를 참조하십시오 . 내용물이 무엇이고 어떻게 사용하는지 알려줍니다.
David Z

13

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

...


반대로, __init__.py당신이 정말로 의미하는 바를 분명히하기 위해 백틱 에 넣을 수 있습니다 . 혼란스러운 초보자를 피하기 위해. :)__init__.pyinit.py
antred

4

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

내 프로젝트에서는 상위 디렉토리에 기본 스크립트가 있고 모듈을 구분하기 위해 모든 지원 모듈을 "모듈"이라는 하위 폴더에 넣었습니다. 내 기본 스크립트에서 다음과 같은 모듈을 가져옵니다 (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"하위 폴더를 찾습니다. 모든 것이 정상입니다.


3

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

그래서 저는 빠르고 더러운 해결책을 썼습니다. 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
]

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


3

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

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

C : \ Users \ example ... \ example

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

import sys
for line in sys: print line

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

import mymodule

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


0

이전 질문에 대한 새로운 옵션입니다.
설치 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.