bestsource

Python: 현재 실행 중인 스크립트와 관련하여 sys.path에 추가하는 가장 좋은 방법

bestsource 2023. 9. 1. 21:10
반응형

Python: 현재 실행 중인 스크립트와 관련하여 sys.path에 추가하는 가장 좋은 방법

스크립트로 가득 찬 디렉토리가 있습니다(예:project/bin나는 또한 도서관이 있습니다.project/lib스크립트가 자동으로 로드하기를 원합니다.각 스크립트의 맨 위에 보통 사용하는 것은 다음과 같습니다.

#!/usr/bin/python
from os.path import dirname, realpath, sep, pardir
import sys
sys.path.append(dirname(realpath(__file__)) + sep + pardir + sep + "lib")

# ... now the real code
import mylib

이것은 좀 번거롭고 보기 흉하며 모든 파일의 시작 부분에 붙여 넣어야 합니다.이것을 하는 더 좋은 방법이 있습니까?

정말로 제가 바라는 것은 다음과 같은 부드러운 것입니다.

#!/usr/bin/python
import sys.path
from os.path import pardir, sep
sys.path.append_relative(pardir + sep + "lib")

import mylib

더 좋은 것은 편집자(또는 액세스 권한을 위임한 다른 사용자)가 정리 프로세스의 일부로 가져오기를 다시 정렬하기로 결정할 때 손상되지 않는 것입니다.

#!/usr/bin/python --relpath_append ../lib
import mylib

그것은 비포식스 플랫폼에 직접 연결되지는 않겠지만, 그것은 모든 것을 깨끗하게 유지할 것입니다.

다음을 사용합니다.

import os, sys
sys.path.append(os.path.join(os.path.dirname(__file__), "lib"))

사용 중:

import sys,os
sys.path.append(os.getcwd())

각 파일을 편집하지 않으려면

  • 일반 파이썬 라이브러리처럼 라이브러리 설치
    또는
  • 세트PYTHONPATH당신에게lib

또는 각 파일에 한 줄씩 추가하려는 경우 맨 위에 가져오기 문을 추가합니다.

import import_my_lib

지킨다import_my_lib.py상자 안에 들어 있는import_my_lib파이썬 경로를 올바르게 설정할 수 있습니다.lib너는 원한다

래퍼 모듈 만들기project/bin/lib다음을 포함합니다.

import sys, os

sys.path.insert(0, os.path.join(
    os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib'))

import mylib

del sys.path[0], sys, os

그런 다음 스크립트 상단의 모든 크래프트를 다음으로 바꿀 수 있습니다.

#!/usr/bin/python
from lib import mylib

python 3.4+ 사용

import sys
from pathlib import Path

# As PosixPath
sys.path.append(Path(__file__).parent / "lib")

# Or as str as explained in https://stackoverflow.com/a/32701221/11043825
sys.path.append(str(Path(__file__).parent / "lib"))

스크립트 내용을 변경하지 않으려면 현재 작업 디렉토리 앞에 추가.$PYthonPATH로(아래 예 참조)

PYTHONPATH=.:$PYTHONPATH alembic revision --autogenerate -m "First revision"

그리고 오늘은 여기까지!

스크립트를 실행할 수 있습니다.python -m관련 루트 dir에서.그리고 "모듈 경로"를 인수로 전달합니다.

예:$ python -m module.sub_module.main # Notice there is no '.py' at the end.


다른 예:

$ tree  # Given this file structure
.
├── bar
│   ├── __init__.py
│   └── mod.py
└── foo
    ├── __init__.py
    └── main.py

$ cat foo/main.py
from bar.mod import print1
print1()

$ cat bar/mod.py
def print1():
    print('In bar/mod.py')

$ python foo/main.py  # This gives an error
Traceback (most recent call last):
  File "foo/main.py", line 1, in <module>
    from bar.mod import print1
ImportError: No module named bar.mod

$ python -m foo.main  # But this succeeds
In bar/mod.py

다음과 같이 여러 번 작업합니다.

import os
import sys

current_path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(current_path, "lib"))

"이 마법 주문을 스크립트의 시작 부분에 추가하면 됩니다."라고 요약할 수 있는 모든 답변에는 문제가 있습니다.코드 한두 줄로 무엇을 할 수 있는지 확인하십시오."그들은 가능한 모든 상황에서 작동하지 않을 것입니다!

예를 들어, 그러한 마법 주문 중 하나는__file__안타깝게도 cx_Freeze를 사용하여 스크립트를 패키지화하거나 IDLE을 사용하는 경우 예외가 발생합니다.

또 다른 그러한 마법 주문은 os.getcwd()를 사용합니다.이것은 명령 프롬프트에서 스크립트를 실행하고 스크립트를 포함하는 디렉토리가 현재 작업 디렉토리인 경우에만 작동합니다(스크립트를 실행하기 전에 cd 명령을 사용하여 디렉토리로 변경한 경우).세상에!만약 당신의 파이썬 스크립트가 PATH 어딘가에 있고 당신이 스크립트 파일의 이름을 입력하는 것만으로 실행했다면 이것이 작동하지 않는 이유를 설명할 필요가 없기를 바랍니다.

다행히도, 제가 실험한 모든 경우에 효과가 있을 마법 주문이 있습니다.불행하게도, 마법 주문은 단지 한두 줄의 코드 이상입니다.

import inspect
import os
import sys

# Add script directory to sys.path.
# This is complicated due to the fact that __file__ is not always defined.

def GetScriptDirectory():
    if hasattr(GetScriptDirectory, "dir"):
        return GetScriptDirectory.dir
    module_path = ""
    try:
        # The easy way. Just use __file__.
        # Unfortunately, __file__ is not available when cx_Freeze is used or in IDLE.
        module_path = __file__
    except NameError:
        if len(sys.argv) > 0 and len(sys.argv[0]) > 0 and os.path.isabs(sys.argv[0]):
            module_path = sys.argv[0]
        else:
            module_path = os.path.abspath(inspect.getfile(GetScriptDirectory))
            if not os.path.exists(module_path):
                # If cx_Freeze is used the value of the module_path variable at this point is in the following format.
                # {PathToExeFile}\{NameOfPythonSourceFile}. This makes it necessary to strip off the file name to get the correct
                # path.
                module_path = os.path.dirname(module_path)
    GetScriptDirectory.dir = os.path.dirname(module_path)
    return GetScriptDirectory.dir

sys.path.append(os.path.join(GetScriptDirectory(), "lib"))
print(GetScriptDirectory())
print(sys.path)

보시다시피, 이것은 쉬운 일이 아닙니다!

사용자:

from site import addsitedir

그러면 임의의 상대 디렉토리를 사용할 수 있습니다!addsitedir('..\lib')두 개의 점은 먼저 하나의 디렉토리를 이동(위로)하는 것을 의미합니다.

이 모든 것은 현재 작업 디렉토리의 시작 위치에 따라 달라집니다.C:\Joe\Jen\Becky인 경우, ir('..\lib') 경로 C:\Joe\Jen\lib로 가져옵니다.

C:\
  |__Joe
      |_ Jen
      |     |_ Becky
      |_ lib

저는 당신의 예에서 셰뱅을 봅니다.bin으로 하는 ./bin/foo.py에, 다는보는python ./bin/foo.py셰방을 사용하여 변경할 수 있는 옵션이 있습니다.$PYTHONPATH변수.

하지만 셰뱅에서 환경 변수를 직접 변경할 수는 없으므로 작은 도우미 스크립트가 필요합니다.을 거놔 요이놔.python.sh의 신의것에.bin폴더:

#!/usr/bin/env bash
export PYTHONPATH=$PWD/lib
exec "/usr/bin/python" "$@"

그리고 나서 당신의 셰뱅을 바꾸세요../bin/foo.py되려고#!bin/python.sh

터미널의 경로로 파이썬 파일을 실행하려고 할 때.

import sys
#For file name
file_name=sys.argv[0]
#For first argument
dir= sys.argv[1]
print("File Name: {}, argument dir: {}".format(file_name, dir)

파일(test.py )을 저장합니다.

실행 중인 시스템.

터미널을 열고 dir where is save file로 이동합니다.그리고 쓰다

python test.py "/home/saiful/Desktop/bird.jpg"

엔터를 누르기

출력:

File Name: test, Argument dir: /home/saiful/Desktop/bird.jpg

언급URL : https://stackoverflow.com/questions/8663076/python-best-way-to-add-to-sys-path-relative-to-the-current-running-script

반응형