파이썬 애플리케이션을위한 최고의 프로젝트 구조는 무엇입니까? [닫은]


730

파이썬에서 사소하지 않은 최종 사용자 데스크탑 (웹이 아닌) 응용 프로그램을 개발하려고한다고 상상해보십시오. 프로젝트의 폴더 계층을 구성하는 가장 좋은 방법은 무엇입니까?

바람직한 기능은 유지 관리 용이성, IDE 친 화성, 소스 제어 분기 / 병합에 대한 적합성 및 쉬운 설치 패키지 생성입니다.

특히:

  1. 소스를 어디에 두나요?
  2. 응용 프로그램 시작 스크립트는 어디에 배치합니까?
  3. IDE 프로젝트를 어디에 배치합니까?
  4. 단위 / 수락 테스트는 어디에 배치합니까?
  5. 구성 파일과 같은 비 Python 데이터를 어디에 두나요?
  6. pyd / so 이진 확장 모듈에 C ++과 같은 비 Python 소스를 어디에 배치합니까?

답변:


377

너무 중요하지 않습니다. 당신을 행복하게하는 것은 효과가있을 것입니다. 파이썬 프로젝트는 단순 할 수 있기 때문에 많은 어리석은 규칙은 없습니다.

  • /scripts또는 /bin이런 종류의 명령 줄 인터페이스에
  • /tests 당신의 테스트를 위해
  • /lib C 언어 라이브러리
  • /doc 대부분의 문서
  • /apidoc Epydoc에서 생성 한 API 문서

그리고 최상위 디렉토리에는 README, Config 및 기타가 포함될 수 있습니다.

어려운 선택은 /src나무 를 사용할지 여부 입니다. 파이썬은 구별이없는 /src, /lib그리고 /binJava 또는 C와 같은있다.

최상위 /src디렉토리는 의미없는 것으로 간주 되므로 최상위 디렉토리는 응용 프로그램의 최상위 아키텍처가 될 수 있습니다.

  • /foo
  • /bar
  • /baz

이 모든 것을 "name-of-my-product"디렉토리에 두는 것이 좋습니다. 따라서라는 애플리케이션을 작성하는 quux경우이 모든 것을 포함하는 디렉토리의 이름은 /quux입니다.

다른 프로젝트 는 모듈 재사용을 PYTHONPATH포함 /path/to/quux/foo할 수 있습니다 QUUX.foo.

필자의 경우 Komodo Edit를 사용하기 때문에 IDE cuft는 단일 .KPF 파일입니다. 실제로 최상위 /quux디렉토리에 넣고 SVN에 추가하는 것을 생략합니다.


23
디렉토리 구조를 에뮬레이트하는 것이 권장되는 오픈 소스 파이썬 프로젝트가 있습니까?
랜스 러싱

4
좋은 예를 보려면 장고를보십시오.
S.Lott

33
장고가 좋은 예라고 생각하지는 않습니다 .sys.path로 트릭을하는 것은 내 책에서 즉각적인 DQ입니다.
Charles Duffy

18
"트릭": Django는 루트 프로젝트 폴더의 부모를 sys.path에 추가하여 모듈을 "project.app.module import klass에서"또는 "app.module import klass에서"로 가져올 수 있습니다.
Jonathan Hartley

3
오, 나는이 트릭을 좋아하고 지금 사용하고 있습니다. 공유 모듈을 다른 디렉토리에 넣고 싶습니다. 시스템 전체에 모듈을 설치하고 싶지 않으며 사람들에게 PYTHONPATH를 수동으로 수정하도록 요청하고 싶지 않습니다. 사람들이 더 나은 것을 제안하지 않는 한, 이것이 실제로 가장 깨끗한 방법이라고 생각합니다.
Yongwei Wu

242

Jean-Paul Calderone의 Python 프로젝트파일 시스템 구조에 따르면 :

Project/
|-- bin/
|   |-- project
|
|-- project/
|   |-- test/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |   
|   |-- __init__.py
|   |-- main.py
|
|-- setup.py
|-- README

23
Project/project/? 아, 두 번째는 패키지 이름입니다.
Cees Timmerman

44
bin 폴더의 실행 파일은 프로젝트 모듈을 어떻게 참조합니까? (파이썬 구문 ../이 include 문에서 허용한다고 생각하지 않습니다 )
ThorSummoner

8
@ThorSummoner 간단합니다. 패키지를 설치했습니다! ( pip install -e /path/to/Project)
Kroltan

22
누군가이 hello.py 및 hello-test.py를 사용 하여이 레이아웃의 샘플을 압축하여 우리에게 사용할 수 있다면 멋질 것입니다.
jeremyjjbrown

8
@Bloke 코어는 -e패키지를 편집 가능한 패키지로 설치 하는 플래그입니다. 즉, 실제 프로젝트 폴더에 대한 링크로 설치합니다. 실행 파일은 import project모듈에 액세스하기 만하면 됩니다.
Kroltan

232

Jean-Paul Calderone 의이 블로그 게시물 은 일반적으로 Freenode의 #python에서 답변으로 제공됩니다.

파이썬 프로젝트의 파일 시스템 구조

하다:

  • 프로젝트와 관련된 디렉토리 이름을 지정하십시오. 예를 들어, 프로젝트 이름이 "Twisted"인 경우 소스 파일의 최상위 디렉토리 이름을 지정하십시오 Twisted. 릴리스를 수행 할 때 버전 번호 접미 부를 포함시켜야합니다 Twisted-2.5.
  • 디렉토리를 만들고 Twisted/bin실행 파일이 있으면 거기에 넣으십시오. .py파이썬 소스 파일 인 경우에도 확장명을 주지 마십시오 . 프로젝트의 다른 곳에 정의 된 주 함수를 가져오고 호출하는 것을 제외하고는 코드를 넣지 마십시오. (약간 주름 : Windows에서는 파일 확장자로 인터프리터가 선택되므로 Windows 사용자는 실제로 .py 확장자를 원합니다. 따라서 Windows 용 패키지를 추가 할 때 추가 할 수 있습니다. 불행히도 쉽게 혼란스러운 트릭은 없습니다 POSIX에서 .py 확장자는 유일한 경고이지만 Windows에서는 실제 버그가 아니라고 생각합니다. 사용자 데이터베이스에 Windows 사용자가 포함되어 있으면 .py 만 선택할 수 있습니다. 사방 확장.)
  • 프로젝트가 단일 Python 소스 파일로 표현 가능한 경우 디렉토리에 넣고 프로젝트와 관련된 이름을 지정하십시오. 예를 들면 다음과 같습니다 Twisted/twisted.py. 여러 소스 파일이 필요한 경우 대신 패키지를 만들고 ( Twisted/twisted/비어있는 Twisted/twisted/__init__.py) 소스 파일을 그 안에 넣으십시오. 예를 들면 다음과 같습니다 Twisted/twisted/internet.py.
  • 단위 테스트를 패키지의 하위 패키지에 넣으십시오 (이것은 위의 단일 Python 소스 파일 옵션이 트릭임을 의미합니다- 단위 테스트에는 항상 하나 이상의 다른 파일이 필요합니다). 예를 들면 다음과 같습니다 Twisted/twisted/test/. 물론로 패키지를 만드십시오 Twisted/twisted/test/__init__.py. 와 같은 파일에 테스트를 배치하십시오 Twisted/twisted/test/test_internet.py.
  • 기분이 좋으면 소프트웨어를 각각 추가 Twisted/README하고 Twisted/setup.py설명하고 설치하십시오.

하지 마십시오 :

  • src또는 라는 디렉토리에 소스를 넣으십시오 lib. 설치하지 않고 실행하기가 어렵습니다.
  • 테스트를 파이썬 패키지 외부에 두십시오. 이로 인해 설치된 버전에 대해 테스트를 실행하기가 어렵습니다.
  • 패키지 작성 에만 A가 들어를 __init__.py에 모든 코드를 넣어 다음과 __init__.py. 패키지 대신 모듈을 만들면 더 간단합니다.
  • 파이썬이 모듈이나 패키지를 포함하는 디렉토리를 가져 오기 경로에 추가하지 않고도 (PYTHONPATH 또는 다른 메커니즘을 통해) 파이썬이 모듈이나 패키지를 가져올 수 있도록 마법의 해킹을 생각해보십시오. 당신은 할 수 없습니다 올바르게 모든 경우를 처리하고 소프트웨어가 자신의 환경에서 작동하지 않는 경우 사용자는 화가 얻을 것이다.

25
이것이 바로 내가 필요한 것입니다. "DONT는 사용자가 모듈이나 패키지를 포함하는 디렉토리를 가져 오기 경로에 추가하지 않고도 파이썬이 모듈이나 패키지를 가져올 수 있도록하기 위해 마법의 해킹을 시도합니다." 알아 둘만 한!
잭 오코너

1
이것은 프로젝트를 어디에 배치해야하는지에 대한 중요한 문서 부분을 언급하지 않습니다.
lpapp

14
"src 또는 lib라는 디렉토리에 소스를 넣으십시오. 설치하지 않고 실행하기가 어렵습니다." 무엇을 설치해야합니까? 이것이 문제를 일으키는 dir 이름입니까, 아니면 그것이 subdir이라는 사실입니까?
피터 Ehrlich

3
"일부 사람들은 모듈 자체 내에서 테스트를 배포해야한다고 주장합니다. 동의하지 않습니다. 사용자의 복잡성을 증가시키는 경우가 많습니다. 많은 테스트 스위트에는 종종 추가 종속성과 런타임 컨텍스트가 필요합니다." python-guide-pt-br.readthedocs.io/en/latest/writing/structure/…
endolith

2
"이것은 설치하지 않고 실행하기가 어렵습니다." -그게 요점입니다
Nick T

123

올바른 방법으로 Python 프로젝트 오픈 소싱을 확인하십시오 .

이 훌륭한 기사 의 프로젝트 레이아웃 부분을 발췌하겠습니다 .

프로젝트를 설정할 때, 레이아웃 (또는 디렉토리 구조)이 올바르게 작동하는 것이 중요합니다. 합리적인 레이아웃은 잠재적 인 기여자가 코드를 찾기 위해 영원히 사냥 할 필요가 없다는 것을 의미합니다. 파일 위치는 직관적입니다. 우리는 기존 프로젝트를 다루고 있기 때문에 아마도 무언가를 움직여야 할 것입니다.

맨 위에서 시작합시다. 대부분의 프로젝트에는 setup.py, README.md, requirements.txt 등과 같은 여러 최상위 파일이 있습니다. 모든 프로젝트에는 세 개의 디렉토리가 있어야합니다.

  • 프로젝트 문서를 포함하는 문서 디렉토리
  • 실제 Python 패키지를 저장하는 프로젝트 이름으로 명명 된 디렉토리
  • 두 곳 중 하나의 테스트 디렉토리
    • 테스트 코드 및 리소스가 포함 된 패키지 디렉토리 아래
    • 독립형 최상위 디렉토리로서 파일을 구성하는 방법을 더 잘 이해하기 위해 다음은 프로젝트 중 하나 인 sandman의 레이아웃에 대한 간략한 스냅 샷입니다.
$ pwd
~/code/sandman
$ tree
.
|- LICENSE
|- README.md
|- TODO.md
|- docs
|   |-- conf.py
|   |-- generated
|   |-- index.rst
|   |-- installation.rst
|   |-- modules.rst
|   |-- quickstart.rst
|   |-- sandman.rst
|- requirements.txt
|- sandman
|   |-- __init__.py
|   |-- exception.py
|   |-- model.py
|   |-- sandman.py
|   |-- test
|       |-- models.py
|       |-- test_sandman.py
|- setup.py

보시다시피, 최상위 파일, docs 디렉토리 (스핑크스가 생성 된 문서를 저장하는 빈 디렉토리 임), sandman 디렉토리 및 sandman 아래의 test 디렉토리가 있습니다.


4
나는 이것을하지만 더 많이 : 나는 'virtualenv env를 자동화하는'env '대상이있는 최상위 Makefile을 가지고 있습니다. ./env/bin/pip install -r requirements.txt; ./env/bin/python setup.py develop '및 일반적으로 env에 의존하고 테스트 종속성을 설치 한 다음 py.test를 실행하는'테스트 '대상입니다.
pjz

@pjz 아이디어를 확장 해 주시겠습니까? 당신은 Makefile같은 수준 에 두는 것에 대해 이야기 하고 setup.py있습니까? 그래서 내가 당신이 올바르게 make env새로운 것을 생성 자동화 venv하고 패키지를 설치하는 것을 이해한다면 ...?
St.Antario

@ St.Antario 정확하게. 언급했듯이 일반적으로 테스트를 실행하는 'test'대상이 있으며 때로는 현재 태그를보고 바퀴를 만들어 pypi로 보내는 'release'대상이 있습니다.
pjz


19

python_boilerplate 템플릿을 사용하여 프로젝트를 시작하십시오 . 이 방법은 모범 사례 (예 : 여기 )를 따르지만 어느 시점에서 프로젝트를 하나 이상의 계란으로 나눌 의사가있는 경우에 더 적합합니다 (그리고 가장 간단한 프로젝트를 제외하고는 무엇이든 믿습니다). 일반적인 상황은 다른 사람의 라이브러리를 로컬에서 수정 한 버전을 사용해야하는 경우입니다).

  • 소스를 어디에 두나요?

    • 상당히 큰 프로젝트의 경우 소스를 여러 개의 계란으로 나누는 것이 좋습니다. 각 계란은에서 별도의 setuptools-layout으로 이동 PROJECT_ROOT/src/<egg_name>합니다.
  • 응용 프로그램 시작 스크립트는 어디에 배치합니까?

    • 이상적인 옵션은 응용 프로그램 시작 스크립트를 entry_point에그 중 하나로 등록하는 것입니다.
  • IDE 프로젝트를 어디에 배치합니까?

    • IDE에 따라 다릅니다. 많은 사람들이 PROJECT_ROOT/.<something>프로젝트의 루트에 물건을 보관하고 있습니다.
  • 단위 / 수락 테스트는 어디에 배치합니까?

    • 각 계란에는 별도의 테스트 세트가 있으며 PROJECT_ROOT/src/<egg_name>/tests디렉토리에 보관됩니다 . 개인적으로 사용하는 것을 선호 py.test합니다.
  • 구성 파일과 같은 비 Python 데이터를 어디에 두나요?

    • 때에 따라 다르지. 비 파이썬 데이터에는 여러 유형이있을 수 있습니다.
      • "자원" , 즉 계란 안에 포장해야하는 데이터. 이 데이터는 패키지 네임 스페이스 내의 해당 에그 디렉토리로 이동합니다. 에서 pkg_resources패키지를 통해 setuptools또는 importlib.resources표준 라이브러리 의 모듈을 통해 Python 3.7부터 사용할 수 있습니다 .
      • "Config-files" , 즉 프로젝트 소스 파일 외부에있는 것으로 간주되지만 응용 프로그램이 실행될 때 일부 값으로 초기화되어야하는 비 Python 파일. 개발하는 동안 나는 그런 파일들을에 보관하는 것을 선호합니다 PROJECT_ROOT/config. 배포를 위해 다양한 옵션이있을 수 있습니다. Windows에서는 %APP_DATA%/<app-name>/config, Linux /etc/<app-name>또는을 사용할 수 있습니다 /opt/<app-name>/config.
      • 생성 된 파일 , 즉 실행 중에 응용 프로그램에서 만들거나 수정할 수있는 파일. PROJECT_ROOT/var개발 중에 그리고 /varLinux 배포 중에 유지하는 것을 선호 합니다.
  • pyd / so 이진 확장 모듈에 C ++과 같은 비 Python 소스를 어디에 배치합니까?
    • 으로 PROJECT_ROOT/src/<egg_name>/native

문서는 일반적으로 PROJECT_ROOT/doc또는 그 안에 들어갑니다 PROJECT_ROOT/src/<egg_name>/doc(일부 계란을 별도의 큰 프로젝트로 간주하는지 여부에 따라 다릅니다). 일부 추가 구성은 PROJECT_ROOT/buildout.cfgand와 같은 파일에 있습니다 PROJECT_ROOT/setup.cfg.


좋은 답변 주셔서 감사합니다! 당신은 나를 위해 많은 것을 분명히했습니다! 계란 하나만 중첩 할 수 있습니까?
Shookie

아니요, 다른 .egg 파일에 .egg 파일을 저장한다는 의미에서 계란을 "중첩"할 수 없으며 [정말 이상한 일이 아닌 한] 이것이 많이 사용될 것으로 기대합니다. 그러나 유용한 코드를 제공하지 않고 빈 패키지를 의존 패키지에 나열하는 "가상"에그를 만드는 것이 가능합니다. 이런 식으로, 사용자가 그러한 패키지를 설치하려고 할 때, 많은 의존적 난을 재귀 적으로 설치할 것입니다.
KT.

@KT 생성 된 데이터를 처리하는 방법에 대해 조금 자세히 설명해 주시겠습니까? 특히, 코드에서 개발과 배포를 어떻게 구별합니까? base_data_location변수 가 있다고 생각 하지만 어떻게 적절하게 설정합니까?
cmyr

1
사람들이 종종 / var / packagename 또는 ~ / .packagename / var 아래에 넣거나 무언가를 "런타임 데이터"라고 말하고 있다고 가정합니다. 대부분의 경우 이러한 선택은 사용자가 변경하지 않아도되는 기본값으로 충분합니다. 이 동작을 조정하고 싶다면 옵션이 풍부하고 모든 것이 최선의 방법이라고 생각하지 않습니다. 일반적인 선택 : a) ~ / .packagename / configfile, b) MY_PACKAGE_CONFIG = / path / to / configfile 내보내기 c) 명령 행 옵션 또는 기능 매개 변수 d) 이들의 조합.
KT.

단일 구성 클래스를 사용하는 것이 일반적입니다.이 클래스는 선호하는 구성 로딩 로직을 처리하고 사용자가 런타임에 설정을 수정할 수있게합니다. 그러나 일반적으로 이것은 별도의 질문 (여기서 어딘가에 묻었을 수도 있음)의 가치가있는 문제라고 생각합니다.
KT.

15

내 경험상, 그것은 단지 반복의 문제입니다. 어디를 가든 데이터와 코드를 배치하십시오. 어쨌든 당신은 틀릴 것입니다. 그러나 상황이 어떻게 형성 될지에 대한 더 나은 아이디어를 얻으면 이러한 종류의 추측을 할 수있는 훨씬 더 나은 위치에있게됩니다.

확장 소스에 관해서는, 파이썬 용 디렉토리와 다양한 다른 언어 용 디렉토리를 포함하는 트렁크 아래에 Code 디렉토리가 있습니다. 개인적으로, 나는 다음에 확장 코드를 자체 리포지토리에 넣는 경향이 있습니다.

그 말로, 나는 나의 초기 지점으로 돌아갑니다. 너무 큰 거래를하지 마십시오. 당신을 위해 일하는 것 같아요. 작동하지 않는 것을 찾으면 변경할 수 있습니다.


네. 나는 그것에 대해 "Pythonic"이 되려고 노력한다. 명시 적은 암시 적보다 낫다. 디렉토리 계층은 쓰여진 것보다 더 많이 읽고 검사된다. 기타
eric

10

Python 이외의 데이터는 setuptoolspackage_data지원을 사용하여 Python 모듈 내에 가장 잘 번들됩니다 . 필자가 권장하는 한 가지는 네임 스페이스 패키지를 사용하여 여러 프로젝트에서 사용할 수있는 공유 네임 스페이스를 만드는 것입니다. 패키지를 넣는 (및 공유 네임 스페이스 를 가질 수 있는) Java 규칙과 매우 유사합니다 .com.yourcompany.yourprojectcom.yourcompany.utils

충분히 분기 된 소스 제어 시스템을 사용하는 경우 브랜치 및 병합은 이름 바꾸기를 통해서도 병합을 처리합니다. 바자 는 특히 이것을 잘합니다.

여기에있는 다른 답변과 달리 src디렉토리 최상위 디렉토리 ( doctest디렉토리와 함께)를 +1하고 있습니다. 문서 디렉토리 트리에 대한 특정 규칙은 사용중인 항목에 따라 다릅니다. 예를 들어 Sphinx 는 빠른 시작 도구가 지원하는 자체 규칙을 가지고 있습니다.

setuptools 및 pkg_resources를 활용하십시오. 이를 통해 다른 프로젝트가 특정 버전의 코드에 더 쉽게 의존 할 수 있습니다 (및 여러 버전을 사용하는 경우 코드가 아닌 다른 파일과 동시에 여러 버전을 설치할 수 있음 package_data).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.