본문 바로가기
Coding

Python에서 setup.py 파일을 사용하여 코드 공유하는 방법

by Emily Blunt 2022. 4. 28.
반응형

Python에서 setup.py 파일을 사용하여 코드 공유하는 방법

 

101 방법에 공유 코드 파이썬 프로젝트 전반에 걸쳐

Unsplash에 있는 AbsolutVision의 사진

다음과 같은 프로젝트 구조가 있습니다.

├── src ├── common
 ├── __init__.py
└── utils.py ├── config
 └── requirements.txt ├── project1
 ├── __init__.py
└── main.py ├── project2
 ├── __init__.py
└── main.py├── README.md

두 하위 프로젝트 모두 그리고 가지고있다 main.py 유사한 코드를 사용하는 파일.

당신은 이것을 저장하고 싶습니다 공유 내부의 코드 utils.py 세 번째 디렉토리에 있는 파일 .

에 저장된 기능을 사용하려면 utils.py 다음 import 문을 main.py 파일 그리고 :

from common.utils import , ...

그리고 당신은 다음을 얻습니다 ModuleNotFound오류:

ModuleNotFoundError: No module named 'common'

그런 다음 import 문을 다음과 같이 수정하려고 시도합니다.

from .utils import 

또는

from ..utils import 

반환 가져오기 오류:

ImportError: attempted relative import with no known parent package

이 문서에서는 이러한 오류가 발생하는 이유와 다음을 사용하여 이 문제를 방지하는 방법을 설명합니다. setup.py Python 패키지를 생성하는 파일.

먼저…

오류는 무엇입니까?

ModuleNotFoundError: '공통'이라는 모듈이 없습니다.

이 오류는 (가상) 환경에 설치되지 않은 Python 패키지/모듈을 가져오려고 할 때 발생합니다. 명령을 실행하는 경우:

pip list

터미널(mac) 또는 명령줄 프롬프트(windows)에서 설치하려는 모듈이 화면에 출력되는 목록에 없을 것입니다. 예를 들어, pip list내 가상 환경(venv)에서 명령을 받은 후 ModuleNotFoundError 나는 얻다:

Package Version
-------------- -------
pip 21.3.1
setuptools 59.0.1

여기에는 에 대한 참조가 포함되어 있지 않습니다. utils.py 안에 패키지 폴더.

ImportError: 알려진 상위 패키지가 없는 상대 가져오기 시도

상대 가져오기 오류는 상위 패키지에서 모듈을 가져오려고 시도하지만 Python에 저장된 다른 상위 패키지가 있을 때 발생합니다. __main__. 본질적으로, 당신은 파이썬이 인식하지 못하는 패키지에서 가져오도록 지시하는 것입니다.

Python이 정보를 저장하는 방법에 대한 훌륭한 설명 __main__ 변수에서 찾을 수 있습니다 [Script vs. Module] 여기에 StackOverflow 답변이 있습니다.

메모: 상대 가져오기는 파이썬적이지 않으며 혼동을 피하고 코드의 가독성을 향상시키기 위해 가능하면 피해야 합니다.

시도했을 수 있는 몇 가지 가능한 비 파이썬 솔루션…

1. sys.path()

원하는 패키지 상위 경로를 sys.path 오류가 발생하기 전에 변수를 가져옵니다. 예를 들어 다음 줄을 main.py 파일:

그러나 일반적으로 다음과 같은 이유로 이 접근 방식을 피하는 것이 좋습니다.

  • 지저분한: 지저분해.
  • 오류 전파: 폴더 위치가 달라 다른 사람이 재사용할 때 오류가 발생하지 않도록 제대로 코딩해야 합니다.
  • 코드 중복: 가져오기 오류가 있는 각 .py 파일에 추가해야 합니다.

2. 구조조정 프로젝트

프로젝트를 재구성하고 각 하위 프로젝트의 main.py 파일을 루트에 저장하여 가져오기가 계층적 디렉토리 구조를 아래로 따를 수 있도록 합니다.

이 솔루션을 채택하지 말아야 하는 두 가지 주요 이유:

  • 지저분한: 프로젝트가 커짐에 따라 이 접근 방식은 무질서하고, 불분명하고, 지저분해집니다.
  • 커스터마이징: 읽기 쉽고 독특한 방식으로 프로젝트를 구성할 수 없습니다.
  • 네이밍: 모두 같은 디렉토리에 있으므로 동일한 이름의 파일은 허용되지 않습니다. 즉, 다음과 같은 고유한 이름을 만들어 내야 합니다. main1.py 그리고 main2.py.

setup.py 구출에…

경험상 많은 모듈에서 재사용할 수 있는 많은 코드가 프로젝트에 있는 경우 Python 패키지로 만드는 것이 좋습니다.

파이썬 패키지란 무엇입니까?

를 포함하는 폴더 __init__.py Python은 패키지로 인식합니다. 패키지 폴더 대개 여러 모듈을 포함합니다.

(가상) 환경에 설치된 패키지는 다음을 사용하여 식별할 수 있습니다. pip list 명령.

setup.py 설정

  • setup.py 파일은 사용자 정의 Python 패키지를 만드는 방법에 대한 정보를 제공합니다. 그것은 파이썬의 setuptools 라이브러리와 기본 파일은 다음과 같습니다.
기본 setup.py 파일

의 주요 세 콰르그 setup() 이다:

  • name — Python 패키지의 이름입니다.
  • install_requires — 포인트 setup.pyrequirements.txt 패키지의 일부가 될 Python 모듈에 필요한 Python 라이브러리가 포함된 파일입니다. 3행과 4행은 setup.py 패키지에서 지정된 위치에서 필요한 Python 패키지를 읽습니다.
  • packages — 원하는 패키지 setup.py 사용자 정의 Python 패키지에 포함합니다. 당신이 사용할 수있는 setuptools.find_packages() 프로젝트의 모든 패키지를 찾거나 수동으로 입력합니다. find_packages() 포함하는 모든 폴더를 식별합니다. __init__.py. 예제 프로젝트 구조의 경우 다음을 실행합니다. find_packages() 다음을 패키지로 반환합니다. __init__.py)
['common', 'project1', 'project2']
  • 우리는 내부에 코드를 패키징하기를 원합니다. 그래서 우리는 추가합니다 project1 그리고 project2 ~로 exclude 콰그:
find_packages(exclude=["project1", "project2"])

패키지 설치

이 글의 "문제점" 부분에 있는 프로젝트 설정을 고려할 때, 다음은 setup.py 위에 스크린샷.

├── src ├── common
 ├── __init__.py
└── utils.py ├── config
 └── requirements.txt ├── project1
 ├── __init__.py
└── main.py ├── project2
 ├── __init__.py
└── main.py ├── setup.py ├── README.md

메모: 그만큼 setup.py 파일은 사용자 정의 패키지를 빌드하는 데 사용되는 패키지의 위치에 있어야 합니다( setup() 패키지 kwarg).

패키지를 생성하려면 상위 폴더 dir로 이동해야 합니다. setup.py 파일을 만들고 다음 명령을 실행합니다.

pip install -e ./

이 기사의 예제 프로젝트의 경우 다음을 실행합니다. pip install -e ./src:

pip install -e ./src를 실행할 때 터미널 stdout

그만큼 -e 패키지를 편집 가능한 모드(동적으로)로 실행하여 개발할 때 코드에 대한 변경 사항을 자동으로 감지하므로 계속해서 패키지를 다시 설치할 필요가 없습니다.

설치가 완료되면 다음을 다시 실행하여 성공적으로 설치되었는지 확인할 수 있습니다.

pip list

이제 패키지와 목록에 나열된 패키지가 표시되어야 합니다. requirements.txt 나열된 패키지에서:

Package Version Editable project location
-------------- ------- -----------------------------
DateTime 4.4
pip 21.3.1
pytz 2022.1
setuptools 59.0.1
simple-package 1.0.0 /Users/danielseal/git_local/Sharing_Code_Example/src
zope.interface 5.4.0

주의 Editable project location 일부 pip list 산출.

원하는 경우 딱딱한 패키지를 (정적으로) 설치하십시오. 즉, 변경하지 않을 안정적인 버전의 경우 간단히 삭제할 수 있습니다. -e 그리고 실행 pip install ./src:

pip install ./src를 실행할 때 터미널 stdout

이 설치는 더 명시적이며 실행 후 다음 출력을 반환합니다. pip list:

Package Version
-------------- -------
DateTime 4.4
pip 21.3.1
pytz 2022.1
setuptools 59.0.1
simple-package 1.0.0 zope.interface 5.4.0
wheel 0.37.1. 

떨어뜨리다 -e 또한 프로젝트에서 패킹을 위한 휠을 빌드합니다. /build 당신이없는 폴더 editable 방법.

메모:

  • 정적 및 동적 설치 모두 .egg-info 파일을 프로젝트에 넣습니다.
  • 달리기 전에 pip install ./src 다음을 사용하여 휠 패키지를 설치하는 것이 좋습니다. pip install wheel 바퀴가 설치되어 있지 않다는 경고를 피하기 위해.
pip intall ./src를 실행한 후의 프로젝트 구조(명시적 설치를 표시하기 위해 -e를 삭제함).

이 단계에서 사용자 정의 Python 패키지를 성공적으로 설치했습니다.

이제 이전에 오류가 발생한 가져오기를 실행할 때 오류가 발생하지 않아야 합니다...

패키지 설치 후 project1/main.py 및 project2/main.py를 실행할 때 stdout.

코멘트

  • 경고: 패키지를 정적으로 설치한 경우(추가하지 않고 -e설치 명령에서) 다음을 추가하여 설치 명령을 다시 실행해야 합니다. --upgrade 또는 -u마지막에 설치하려는 패키지 폴더 내의 코드를 변경하면( 이 예의 경우):
pip install ./src --upgrade
  • 편집 가능: 언급했듯이 다음을 사용하여 패키지를 설치합니다. pip install -e ./src 편집 가능한 모드로 패키지를 설치합니다. 추가되지 않습니다 /build 프로젝트에 폴더
  • 버전 관리: Python 패키지에 대한 새로운 기능이나 수정 사항을 구현한 경우 업데이트하는 것이 좋습니다. 버전 kwarg 인 setup() 좋은 버전 관리를 촉진합니다.

pip로 로컬 Python 패키지 업데이트에 대한 이 StackOverflow 피드는 -u(업그레이드) 및 -e(편집 가능)의 사용을 정말 잘 설명합니다.