[python] Python-루트 프로젝트 구조의 경로 가져 오기

프로젝트 루트에 구성 파일이있는 python 프로젝트가 있습니다. 프로젝트 전체에 걸쳐 몇 가지 다른 파일에서 구성 파일에 액세스해야합니다.

따라서 다음과 같이 보입니다. <ROOT>/configuration.conf
<ROOT>/A/a.py,<ROOT>/A/B/b.py (b, a.py가 구성 파일에 액세스 할 때).

내가 속한 프로젝트 내의 어떤 파일에 의존하지 않고 프로젝트 루트 및 구성 파일에 대한 경로를 얻는 가장 / 쉬운 방법은 무엇입니까? 즉 사용하지 않고 ../../? 프로젝트 루트의 이름을 알고 있다고 가정해도됩니다.



답변

Django가하는 방식으로이를 수행 할 수 있습니다 . 프로젝트의 최상위 수준에있는 파일에서 프로젝트 루트에 대한 변수를 정의합니다. 예를 들어 프로젝트 구조가 다음과 같은 경우 :

project/
    configuration.conf
    definitions.py
    main.py
    utils.py

에서 definitions.py정의 할 수 있습니다 (이 필요함 import os).

ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) # This is your Project Root

따라서 프로젝트 루트를 알고 있으면 구성 위치를 가리키는 변수를 만들 수 있습니다 (이는 어디에서나 정의 할 수 있지만 논리적 위치는 상수가 정의 된 위치에 배치하는 것입니다-예 definitions.py).

CONFIG_PATH = os.path.join(ROOT_DIR, 'configuration.conf')  # requires `import os`

그런 다음, 당신은 쉽게 가져 오기 문 (예에서와 (다른 파일의 단위) 일정에 액세스 할 수 있습니다 utils.py) from definitions import CONFIG_PATH.


답변

다른 답변은 프로젝트의 최상위 수준에서 파일을 사용하기위한 조언입니다. pathlib.Pathparent(Python 3.4 이상) 을 사용하는 경우에는 필요하지 않습니다 . README.md및 제외 된 모든 파일 utils.py이 생략 된 다음 디렉토리 구조를 고려하십시오 .

project
   README.md
|
└───src
      utils.py
|   |   ...
|   ...

에서 utils.py우리는 다음과 같은 기능을 정의합니다.

from pathlib import Path

def get_project_root() -> Path:
    return Path(__file__).parent.parent

프로젝트의 모든 모듈에서 다음과 같이 프로젝트 루트를 가져올 수 있습니다.

from src.utils import get_project_root

root = get_project_root()

장점 : 호출하는 모든 모듈 get_project_root은 프로그램 동작을 변경하지 않고 이동할 수 있습니다. 모듈 utils.py이 이동 된 경우에만 업데이트 get_project_root하고 가져 오기를 수행해야합니다 (리팩터링 도구를 사용하여 자동화 할 수 있음).


답변

이전의 모든 솔루션은 내가 필요하다고 생각하는 것에 대해 지나치게 복잡해 보였으며 종종 저에게 적합하지 않았습니다. 다음 한 줄 명령은 원하는 작업을 수행합니다.

import os
ROOT_DIR = os.path.abspath(os.curdir)


답변

“루트”모듈의 경로를 얻으려면 다음을 사용할 수 있습니다.

import os
import sys
os.path.dirname(sys.modules['__main__'].__file__)

그러나 더 흥미롭게도 최상위 모듈에 구성 “객체”가있는 경우 다음과 같이 읽을 수 있습니다.

app = sys.modules['__main__']
stuff = app.config.somefunc()


답변

이를 달성하는 표준 방법 pkg_resourcessetuptools패키지의 일부인 모듈 을 사용하는 것 입니다. setuptools설치 가능한 파이썬 패키지를 만드는 데 사용됩니다.

당신이 사용할 수있는 pkg_resources문자열로 원하는 파일의 내용을 반환하고 사용할 수 있습니다pkg_resources 시스템에서 원하는 파일의 실제 경로를 가져 오는 데 .

라는 패키지가 있다고 가정 해 보겠습니다 stackoverflow.

stackoverflow/
|-- app
|   `-- __init__.py
`-- resources
    |-- bands
    |   |-- Dream\ Theater
    |   |-- __init__.py
    |   |-- King's\ X
    |   |-- Megadeth
    |   `-- Rush
    `-- __init__.py

3 directories, 7 files

이제 모듈에서 Rush 파일에 액세스하려고한다고 가정 해 보겠습니다 app.run. 사용 pkg_resources.resouces_filename경로 러쉬와 얻을 pkg_resources.resource_string러쉬의 내용을 얻는을; 따라서 :

import pkg_resources

if __name__ == "__main__":
    print pkg_resources.resource_filename('resources.bands', 'Rush')
    print pkg_resources.resource_string('resources.bands', 'Rush')

출력 :

/home/sri/workspace/stackoverflow/resources/bands/Rush
Base: Geddy Lee
Vocals: Geddy Lee
Guitar: Alex Lifeson
Drums: Neil Peart

이것은 파이썬 경로의 모든 패키지에서 작동합니다. 따라서 lxml.etree시스템에 존재하는 위치를 알고 싶다면 :

import pkg_resources

if __name__ == "__main__":
    print pkg_resources.resource_filename('lxml', 'etree')

산출:

/usr/lib64/python2.7/site-packages/lxml/etree

요점은이 표준 방법을 사용하여 시스템에 설치된 파일 (예 : pip install xxx 또는 yum -y install python-xxx) 및 현재 작업중인 모듈 내에있는 파일에 액세스 할 수 있다는 것입니다.


답변

아래 코드는 프로젝트 루트까지 경로를 반환합니다.

import sys
print(sys.path[1])


답변

시험:

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))