스크립트로 Python 가상 환경 자동화

12957 단어 pythonbashzsh

문제



파이썬 가상 환경을 만들 때마다 저를 짜증나게 하는 것이 2가지 있습니다.

NOTE

Below instructions are related to the python's default venv module.

If you are using any other version/virtual environment management tools,
like Conda, Poetry, Pyenv, below doesn't apply.



첫 번째는 매번 입력해야 한다는 것입니다.

$ python -m venv ./.venv
$ . ./.venv/bin/activate
# or
# $ source ./.venv/bin/activate


두 번째는 패키지를 설치한 후 아래에 표시된다는 것입니다pip.
버전 경고:

WARNING: You are using pip version 21.1.1; however, version 22.0.4 is available. You should consider upgrading via the '/path/to/project/.venv/bin/python3.8 -m pip install --upgrade pip' command.


이는 python -m venvpython -m ensurepip를 호출하여 pip를 설치하기 때문에 예상되는 동작입니다.

그리고 pip는 거의 구 버전인 번들 버전으로 설치되어 있기 때문에 글로벌 업그레이드 방법이 없습니다. 아래와 같이 확인할 수 있습니다.

>>> import ensurepip
>>> ensurepip.version()
'21.1.1'


ensurepip 문서에 언급된 대로 아래 명령을 사용하여 최신 버전으로 업그레이드할 수는 없지만:

$ python -m ensurepip --upgrade

ensurepip--upgrade 옵션이 있어도 번들 버전만 설치하기 때문입니다.

번들로 제공되는 pipsetuptools를 업데이트하는 공식 옵션은 아직 없습니다.

해결책



좋아, 우리는 개발자이기 때문에 항상 우리의 방법을 찾고 우리의 필요에 맞는 솔루션을 생산합니다.

내 솔루션은 쉘 스크립트에서 제공됩니다. .zshrc , .bashrc , config.fish 와 같은 셸 구성 파일에 넣을 수 있습니다.

아래 기능을 사용하여 ve 명령을 입력하면 내 가상 환경이 생성됩니다. 존재하지 않는 경우 활성화하고 최신pip 버전으로 업그레이드하십시오.

# 0. If not already in virtualenv:
# 0.1. If virtualenv already exists activate it,
# 0.2. If not create it with global packages, update pip then activate it
# 1. If already in virtualenv: just give info
#
# Usage:
# $ ve
# or
# $ ve python3.9
# or
# $ ve python3.9 ./.venv-diff
ve() {
    local py=${1:-python3.8}
    local venv="${2:-./.venv}"

    local bin="${venv}/bin/activate"

    # If not already in virtualenv
    # $VIRTUAL_ENV is being set from $venv/bin/activate script
      if [ -z "${VIRTUAL_ENV}" ]; then
        if [ ! -d ${venv} ]; then
            echo "Creating and activating virtual environment ${venv}"
            ${py} -m venv ${venv} --system-site-package
            echo "export PYTHON=${py}" >> ${bin}    # overwrite ${python} on .zshenv
            source ${bin}
            echo "Upgrading pip"
            ${py} -m pip install --upgrade pip
        else
            echo "Virtual environment  ${venv} already exists, activating..."
            source ${bin}
        fi
    else
        echo "Already in a virtual environment!"
    fi
}


이 함수는 복잡해 보일 수 있으므로 한 줄씩 살펴보겠습니다.
$1는 원하는 파이썬 버전인 첫 번째 인수이고, $2ve() 함수에 제공되는 가상 환경의 이름/디렉토리인 두 번째 인수입니다. 제공된 인수가 없으면 함수는 기본값( python3.8.venv )을 사용합니다. 필요에 따라 이러한 기본값을 사용할 수 있습니다.

ve() {
    local py=${1:-python3.8}
    local venv="${2:-./.venv}"

    local bin="${venv}/bin/activate"
    ...
}


다음과 같은 위치 인수를 제공할 수 있습니다.

$ ve python3.9 .venv2


로컬variables을 생성한 후 이미 가상 환경에 있는 경우 "이미 가상 환경에 있음"메시지만 표시됩니다. $VIRTUAL_ENVactivate 스크립트에서 내보낸 .venv/bin/activate라는 환경 변수가 있는지 확인하여 가상 환경에 있는지 여부를 결정합니다.

ve() {
    ...

    if [ -z "${VIRTUAL_ENV}" ]; then
        ...
    else
        echo "Already in a virtual environment!"
    fi
}


가상 환경에 있지 않은 경우 .venv 디렉토리가 있는지 여부를 제어합니다. 디렉토리가 존재하면 다음과 같이 활성화됩니다.

ve() {
    ...

    if [ -z "${VIRTUAL_ENV}" ]; then
        if [ ! -d ${venv} ]; then
            ...
        else
            echo "Virtual environment  ${venv} already exists, activating..."
            source ${bin}
        fi

    else
        ...
    fi
}


그러나 .venv 디렉토리가 존재하지 않으면 다음과 같이 됩니다.
  • 글로벌 패키지가 포함된 가상 환경.venv 생성(7행),
  • 원하는 Python 버전 환경 변수 내보내기를 activate 스크립트에 추가(8행)
  • 가상 환경 활성화(9행)
  • 현재pip 버전을 최신 버전으로 업그레이드(11행)

  • ve() {
        ...
    
        if [ -z "${VIRTUAL_ENV}" ]; then
            if [ ! -d ${venv} ]; then
                echo "Creating and activating virtual environment ${venv}"
                ${py} -m venv ${venv} --system-site-package
                echo "export PYTHON=${py}" >> ${bin}    # overwrite ${python} on .zshenv
                source ${bin}
                echo "Upgrading pip"
                ${py} -m pip install --upgrade pip
            else
                ...
            fi
    
        else
            ...
        fi
    }
    


    You probably don't need line 8, I'm adding this, because using this environment variable in my other aliases/functions/binaries.



    결론



    결국 이 셸 스크립트로 성가신 버그를 해결하고 다시 생산성을 높일 수 있었습니다.

    이 스크립트는 이 gist 또는 내 function 저장소의 dotfiles에서 찾을 수 있습니다.

    모두 끝났습니다!


    변경 로그
  • 2022-05-10: gist 및 dotfiles 링크 참조 추가됨

  • 슈어핍

    좋은 웹페이지 즐겨찾기