source

코드 저장소를 사용할 때 리소스의 상대 경로를 참조하는 방법

factcode 2022. 12. 25. 09:41
반응형

코드 저장소를 사용할 때 리소스의 상대 경로를 참조하는 방법

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

다음과 같은 작업을 수행할 수 있습니다.

thefile = open('test.csv')

또는 다음과 같이 입력합니다.

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

스크립트가 1개의 특정 디렉토리 또는 디렉토리의 서브셋에서 실행되고 있는 경우에만 동작합니다.

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

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_displaces를 사용하는 것 같습니다.

당신의 경우, 그 예는 다음과 같습니다.

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이 설치되지 않았습니다.이 현란한 사진들이 도움이 되길 바라며

├── 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

MANIFEST.in

recursive-include cnn_client/resources *

표준 setup.py을 사용하여 용골을 작성.pip은 휠 파일을 설치했다.인스톨 후에, 리소스가 인스톨 되어 있는지를 확인합니다.그들은 그렇다.

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()

그리고 그것은 동작한다.

여러 장소에 배포하는 코드가 있다고 하셨기 때문에 파일에만 국한되지 않는 리소스를 배포하기 위해 파이썬 생태계를 사용해야 합니다.또한 zip 아카이브 내의 파일에 액세스할 수 있도록 지원하므로 번거롭지 않습니다.

Previously, this was handeled with 이전에, 이것은 다음 명령으로 처리되었습니다.pkg_resources부에서setuptools그러나 점점 더 많은 툴이 등장함에 따라 생태계는 변화하고 있습니다.python 3.7 이후 importlib.resources를 사용해야 합니다.

import importlib.resources
with importlib.resources.open_text('mypackage.somedirectory','text.csv') as f:
    print(f.read()) # or whatever

그러나 패키지 리소스를 포함하려면 설치 관리자를 지시해야 합니다.그러나 패키지 리소스를 포함하도록 설치 관리자도 지시해야 합니다.그렇지, 으 면 otherwise,,?pip install mypackage데이터 파일을 업데이트하지 않을 것입니다.데이터 파일을 번들하지 않습니다.

그렇게 하는 방법은 여러 가지가 있지만, 한 가지 방법은 더하는 것입니다.

[options.package_data]
mypackage = 
    "somedirectory/*.csv"

의 에 your에setup.cfg을 사용할 때도 이 있습니다.setup.py ★★★★★★★★★★★★★★★★★」pyproject.toml자세한 계정은 setuptools 홈페이지에서 확인할 수 있습니다.

이 질문에 대한 답을 찾기 위해 오랜 시간을 소비했지만, 마침내 답을 얻었습니다(실제로 매우 간단합니다).

import sys
import os
sys.path.append(os.getcwd() + '/your/subfolder/of/choice')

# now import whatever other modules you want, both the standard ones,
# as the ones supplied in your subfolders

이것은 python의 디렉토리에 서브폴더의 상대적인 패스를 추가해 참조합니다.이것은 꽤 빠르고 더럽지만, 그것은 매력적으로 작동합니다.

언급URL : https://stackoverflow.com/questions/1270951/how-to-refer-to-relative-paths-of-resources-when-working-with-a-code-repository

반응형