[python] 코드 리포지토리 작업시 리소스의 상대 경로를 참조하는 방법

우리는 Windows와 Linux 모두에 배포되는 코드 리포지토리를 사용하고 있으며 때로는 다른 디렉토리에 있습니다. 프로젝트 내부의 모듈 중 하나가 프로젝트의 비 Python 리소스 (CSV 파일 등) 중 하나를 어떻게 참조해야합니까?

우리가 다음과 같은 일을하면 :

thefile=open('test.csv')

또는:

thefile=open('../somedirectory/test.csv')

스크립트가 하나의 특정 디렉토리 또는 디렉토리의 서브 세트에서 실행될 때만 작동합니다.

내가하고 싶은 일은 다음과 같습니다.

path=getBasePathOfProject()+'/somedirectory/test.csv'
thefile=open(path)

가능합니까?



답변

현재 파일 경로에 상대적인 파일 이름을 사용하십시오. ‘./my_file’의 예 :

fn = os.path.join(os.path.dirname(__file__), 'my_file')

Python 3.4 이상 에서는 pathlib 를 사용할 수도 있습니다 .

fn = pathlib.Path(__file__).parent / 'my_file'


답변

설정 도구를 사용하거나 배포 (setup.py 설치)하는 경우 이러한 패키지 된 리소스에 액세스하는 “올바른”방법은 package_resources를 사용하는 것 같습니다.

귀하의 경우 예는

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")

물론 리소스를 읽고 이진 데이터를 읽는 것은 my_data의 값입니다.

파일 이름이 필요하면 사용할 수도 있습니다.

resource_filename(package_or_requirement, resource_name)

예:

resource_filename("MyPackage","foo.dat")

장점은 계란과 같은 아카이브 배포 일지라도 작동하도록 보장한다는 것입니다.

http://packages.python.org/distribute/pkg_resources.html#resourcemanager-api를 참조 하십시오.


답변

Python에서 경로는 현재 작업 디렉토리에 상대적 이며, 대부분의 경우 프로그램을 실행하는 디렉토리입니다. 현재 작업 디렉토리는 현재 모듈 파일에 상대 경로를 사용하므로 항상 나쁜 선택이다, 아주 가능성이없는 모듈 파일의 디렉토리와 동일하다.

절대 경로를 사용하는 것이 가장 좋습니다.

import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,'test.cvs')


답변

나는 종종 이와 비슷한 것을 사용합니다 :

import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 'datadir'))

# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here('datadir')

pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
    f = open(pathjoin(DATA_DIR, fn))
    # ...

변수

__file__

는 코드를 작성하는 스크립트의 파일 이름을 보유하므로 스크립트에 상대적인 경로를 만들 수 있지만 여전히 절대 경로로 작성됩니다. 몇 가지 이유로 꽤 잘 작동합니다.

  • 경로는 절대적이지만 여전히 상대적
  • 프로젝트는 여전히 상대 컨테이너에 배포 할 수 있습니다

그러나 플랫폼 호환성에주의해야합니다. Windows의 os.pathsep는 UNIX와 다릅니다.


답변

import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)

또한를 cwd사용하여 정규화하려고합니다 os.path.abspath(os.getcwd()). 자세한 내용은 여기를 참조하십시오 .


답변

빌드 __file__변수를 사용할 수 있습니다 . 현재 파일의 경로를 포함합니다. 프로젝트 루트의 모듈에서 getBaseOfProject를 구현합니다. 거기에서 나는 경로의 일부를 얻고 그것을 __file__반환 할 것입니다. 이 방법은 프로젝트의 어느 곳에서나 사용할 수 있습니다.


답변

나는 여기에 조금 넘어졌다. 일부 리소스 파일을 휠 파일로 패키징하고 액세스하려고했습니다. 매니페스트 파일을 사용하여 패키징을 수행했지만 하위 디렉토리가 아닌 한 pip install이 설치하지 않았습니다. 이 sceen 샷을 기대하면 도움이 될 것입니다

├── cnn_client
   ├── image_preprocessor.py
   ├── __init__.py
   ├── resources
      ├── mscoco_complete_label_map.pbtxt
      ├── retinanet_complete_label_map.pbtxt
      └── retinanet_label_map.py
   ├── tf_client.py

매니페스트

recursive-include cnn_client/resources *

표준 setup.py를 사용하여 웰을 생성했습니다. pip는 wheel 파일을 설치했습니다. 설치 후 리소스가 설치되어 있는지 확인하십시오. 그들은

ls /usr/local/lib/python2.7/dist-packages/cnn_client/resources

mscoco_complete_label_map.pbtxt
retinanet_complete_label_map.pbtxt
 retinanet_label_map.py  

tfclient.py에서 이러한 파일에 액세스하십시오. …에서

templates_dir = os.path.join(os.path.dirname(__file__), 'resources')
 file_path = os.path.join(templates_dir, \
            'mscoco_complete_label_map.pbtxt')
        s = open(file_path, 'r').read()

그리고 작동합니다.