Python 애플리케이션에 가장 적합한 프로젝트 구조는 무엇입니까? [닫은]
Python으로 사소하지 않은 최종 사용자 데스크톱 (웹이 아님) 애플리케이션을 개발하고 싶다고 상상해보십시오. 프로젝트의 폴더 계층 구조를 구성하는 가장 좋은 방법은 무엇입니까?
바람직한 기능은 유지 관리의 용이성, IDE 친 화성, 소스 제어 분기 / 병합에 대한 적합성 및 설치 패키지의 쉬운 생성입니다.
특히:
- 소스를 어디에 두나요?
- 응용 프로그램 시작 스크립트를 어디에 넣습니까?
- IDE 프로젝트를 어디에 두어야합니까?
- 단위 / 수락 테스트는 어디에 두나요?
- 구성 파일과 같은 비 Python 데이터를 어디에 넣습니까?
- pyd / so 바이너리 확장 모듈 용 C ++와 같은 비 Python 소스를 어디에 두나요?
그다지 중요하지 않습니다. 당신을 행복하게 만드는 것은 무엇이든지 효과가있을 것입니다. 파이썬 프로젝트는 간단 할 수 있기 때문에 어리석은 규칙은 많지 않습니다.
/scripts
또는/bin
그런 종류의 명령 줄 인터페이스 관련/tests
당신의 테스트를 위해/lib
C 언어 라이브러리 용/doc
대부분의 문서/apidoc
Epydoc에서 생성 한 API 문서 용.
그리고 최상위 디렉토리에는 README, Config 및 기타 항목이 포함될 수 있습니다.
어려운 선택은 /src
나무 를 사용할지 여부 입니다. 파이썬은 구별이없는 /src
, /lib
그리고 /bin
Java 또는 C와 같은있다.
최상위 /src
디렉토리는 일부 사람들에게 무의미한 것으로 간주 되기 때문에 최상위 디렉토리는 애플리케이션의 최상위 아키텍처가 될 수 있습니다.
/foo
/bar
/baz
이 모든 것을 "내 제품 이름"디렉토리에 두는 것이 좋습니다. 따라서라는 응용 프로그램을 작성하는 quux
경우이 모든 항목을 포함하는 디렉토리의 이름은 /quux
.
PYTHONPATH
그러면 다른 프로젝트의 /path/to/quux/foo
는 QUUX.foo
모듈 을 재사용하도록 포함 할 수 있습니다 .
제 경우에는 Komodo Edit를 사용하기 때문에 IDE cuft는 단일 .KPF 파일입니다. 나는 실제로 /quux
그것을 최상위 디렉토리에 넣고 SVN에 추가하는 것을 생략합니다.
Jean-Paul Calderone의 Python 프로젝트 파일 시스템 구조에 따르면 :
Project/
|-- bin/
| |-- project
|
|-- project/
| |-- test/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- setup.py
|-- README
Jean-Paul Calderone 의이 블로그 게시물 은 일반적으로 Freenode의 #python에서 답변으로 제공됩니다.
Python 프로젝트의 파일 시스템 구조
하다:
- 프로젝트와 관련된 디렉토리 이름을 지정하십시오. 예를 들어 프로젝트 이름이 'Twisted'인 경우 소스 파일의 최상위 디렉토리 이름을 지정합니다
Twisted
. 릴리스를 수행 할 때 버전 번호 접미사를 포함해야합니다Twisted-2.5
..- create a directory
Twisted/bin
and put your executables there, if you have any. Don't give them a.py
extension, even if they are Python source files. Don't put any code in them except an import of and call to a main function defined somewhere else in your projects. (Slight wrinkle: since on Windows, the interpreter is selected by the file extension, your Windows users actually do want the .py extension. So, when you package for Windows, you may want to add it. Unfortunately there's no easy distutils trick that I know of to automate this process. Considering that on POSIX the .py extension is a only a wart, whereas on Windows the lack is an actual bug, if your userbase includes Windows users, you may want to opt to just have the .py extension everywhere.)- If your project is expressable as a single Python source file, then put it into the directory and name it something related to your project. For example,
Twisted/twisted.py
. If you need multiple source files, create a package instead (Twisted/twisted/
, with an emptyTwisted/twisted/__init__.py
) and place your source files in it. For example,Twisted/twisted/internet.py
.- put your unit tests in a sub-package of your package (note - this means that the single Python source file option above was a trick - you always need at least one other file for your unit tests). For example,
Twisted/twisted/test/
. Of course, make it a package withTwisted/twisted/test/__init__.py
. Place tests in files likeTwisted/twisted/test/test_internet.py
.- add
Twisted/README
andTwisted/setup.py
to explain and install your software, respectively, if you're feeling nice.Don't:
- put your source in a directory called
src
orlib
. This makes it hard to run without installing.- put your tests outside of your Python package. This makes it hard to run the tests against an installed version.
- create a package that only has a
__init__.py
and then put all your code into__init__.py
. Just make a module instead of a package, it's simpler.- try to come up with magical hacks to make Python able to import your module or package without having the user add the directory containing it to their import path (either via PYTHONPATH or some other mechanism). You will not correctly handle all cases and users will get angry at you when your software doesn't work in their environment.
Check out Open Sourcing a Python Project the Right Way.
Let me excerpt the project layout part of that excellent article:
When setting up a project, the layout (or directory structure) is important to get right. A sensible layout means that potential contributors don't have to spend forever hunting for a piece of code; file locations are intuitive. Since we're dealing with an existing project, it means you'll probably need to move some stuff around.
Let's start at the top. Most projects have a number of top-level files (like setup.py, README.md, requirements.txt, etc). There are then three directories that every project should have:
- A docs directory containing project documentation
- A directory named with the project's name which stores the actual Python package
- A test directory in one of two places
- Under the package directory containing test code and resources
- As a stand-alone top level directory To get a better sense of how your files should be organized, here's a simplified snapshot of the layout for one of my projects, 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
As you can see, there are some top level files, a docs directory (generated is an empty directory where sphinx will put the generated documentation), a sandman directory, and a test directory under sandman.
The "Python Packaging Authority" has a sampleproject:
https://github.com/pypa/sampleproject
It is a sample project that exists as an aid to the Python Packaging User Guide's Tutorial on Packaging and Distributing Projects.
Try starting the project using the python_boilerplate template. It largely follows the best practices (e.g. those here), but is better suited in case you find yourself willing to split your project into more than one egg at some point (and believe me, with anything but the simplest projects, you will. One common situation is where you have to use a locally-modified version of someone else's library).
Where do you put the source?
- For decently large projects it makes sense to split the source into several eggs. Each egg would go as a separate setuptools-layout under
PROJECT_ROOT/src/<egg_name>
.
- For decently large projects it makes sense to split the source into several eggs. Each egg would go as a separate setuptools-layout under
Where do you put application startup scripts?
- The ideal option is to have application startup script registered as an
entry_point
in one of the eggs.
- The ideal option is to have application startup script registered as an
Where do you put the IDE project cruft?
- Depends on the IDE. Many of them keep their stuff in
PROJECT_ROOT/.<something>
in the root of the project, and this is fine.
- Depends on the IDE. Many of them keep their stuff in
Where do you put the unit/acceptance tests?
- Each egg has a separate set of tests, kept in its
PROJECT_ROOT/src/<egg_name>/tests
directory. I personally prefer to usepy.test
to run them.
- Each egg has a separate set of tests, kept in its
Where do you put non-Python data such as config files?
- It depends. There can be different types of non-Python data.
- "Resources", i.e. data that must be packaged within an egg. This data goes into the corresponding egg directory, somewhere within package namespace. It can be used via
pkg_resources
package. - "Config-files", i.e. non-Python files that are to be regarded as external to the project source files, but have to be initialized with some values when application starts running. During development I prefer to keep such files in
PROJECT_ROOT/config
. For deployment there can be various options. On Windows one can use%APP_DATA%/<app-name>/config
, on Linux,/etc/<app-name>
or/opt/<app-name>/config
. - Generated files, i.e. files that may be created or modified by the application during execution. I would prefer to keep them in
PROJECT_ROOT/var
during development, and under/var
during Linux deployment.
- "Resources", i.e. data that must be packaged within an egg. This data goes into the corresponding egg directory, somewhere within package namespace. It can be used via
- It depends. There can be different types of non-Python data.
- Where do you put non-Python sources such as C++ for pyd/so binary extension modules?
- Into
PROJECT_ROOT/src/<egg_name>/native
- Into
Documentation would typically go into PROJECT_ROOT/doc
or PROJECT_ROOT/src/<egg_name>/doc
(this depends on whether you regard some of the eggs to be a separate large projects). Some additional configuration will be in files like PROJECT_ROOT/buildout.cfg
and PROJECT_ROOT/setup.cfg
.
In my experience, it's just a matter of iteration. Put your data and code wherever you think they go. Chances are, you'll be wrong anyway. But once you get a better idea of exactly how things are going to shape up, you're in a much better position to make these kinds of guesses.
As far as extension sources, we have a Code directory under trunk that contains a directory for python and a directory for various other languages. Personally, I'm more inclined to try putting any extension code into its own repository next time around.
With that said, I go back to my initial point: don't make too big a deal out of it. Put it somewhere that seems to work for you. If you find something that doesn't work, it can (and should) be changed.
Non-python data is best bundled inside your Python modules using the package_data
support in setuptools. One thing I strongly recommend is using namespace packages to create shared namespaces which multiple projects can use -- much like the Java convention of putting packages in com.yourcompany.yourproject
(and being able to have a shared com.yourcompany.utils
namespace).
Re branching and merging, if you use a good enough source control system it will handle merges even through renames; Bazaar is particularly good at this.
Contrary to some other answers here, I'm +1 on having a src
directory top-level (with doc
and test
directories alongside). Specific conventions for documentation directory trees will vary depending on what you're using; Sphinx, for instance, has its own conventions which its quickstart tool supports.
Please, please leverage setuptools and pkg_resources; this makes it much easier for other projects to rely on specific versions of your code (and for multiple versions to be simultaneously installed with different non-code files, if you're using package_data
).
'developer tip' 카테고리의 다른 글
CSS 폭발 관리 (0) | 2020.09.30 |
---|---|
HTML Canvas를 gif / jpg / png / pdf로 캡처 하시겠습니까? (0) | 2020.09.30 |
모듈의 경로를 검색하는 방법은 무엇입니까? (0) | 2020.09.30 |
주어진 40 억 중 하나가 아닌 정수 찾기 (0) | 2020.09.30 |
앱 스토어에서 앱에 연결하는 방법 (0) | 2020.09.30 |