如何组织一个Python项目?

82

我刚学习Python并开始一个小项目,但是我对如何按“Python方式”组织文件夹有一些疑问。

我在我的开发环境中使用PyDev,当我创建一个新项目时,会创建一个名为src的文件夹。

+ src

现在,在PyDev中,我可以创建Pydev模块PyDev包

我需要以以下方式组织我的项目:

+ Indicators
    - Moving_averages.py
    - Stochastics.py
+ Strategies
    - Moving_averages_cross.py
- example.py

如何按照模块和包进行组织?什么是模块和包的含义?


1
我可以推荐这个链接,它来自于Python官方教程中的模块部分。它非常清晰明了,易于理解。 - LiorK
8个回答

51

包基本上是一个带有 __init__.py 文件的文件夹,通常包含一些模块,其中模块是一个 *.py 文件。它主要与 import 有关。如果您将 __init__.py 添加到 Indicators 中,您可以使用:

from Indicators.Stochastics import *
或者
from Indicators import Stochastics

顺便说一下,我建议保持模块/包名称小写。这不会影响功能,但更符合Python的风格。


43

从文件系统的角度来看,一个模块是以.py结尾的文件,而一个包是包含模块和(嵌套)包的文件夹。如果一个文件夹包含一个__init__.py文件,Python会将其识别为一个包。

文件结构如下所示:

some/
    __init__.py
    foofoo.py
    thing/
        __init__.py
        barbar.py

定义了一个名为some的包,其中包含一个名为foofoo的模块以及一个嵌套的包thing,再次包含一个名为barbar的模块。但是,在使用包和模块时,您实际上并不区分这两种类型:

import some

some.dothis() # dothis is defined in 'some/__init__.py'

import some.foofoo # <- module
import some.thing # <- package

在选择命名您的包/模块时,请遵循PEP8(即使用小写字母)。


3
如果我只导入某些内容,我能否从 foofoo.py 调用函数?我对 __init__.py 感到困惑,应该放什么东西在那里? - Jay Wang
@JayWong 不强制在 __init__.py 中放置任何内容,但这有助于 Python 将当前文件夹视为模块并将 *.py 文件视为包。每当您导入一个模块时,__init__.py 文件都会运行并执行其中的任何内容。 - Jawad Mehmood

28

请查看python-package-template

目录结构

    .
    |-- bin
    |   `-- my_program
    |-- docs
    |   `-- doc.txt
    |-- my_program
    |   |-- data
    |   |   `-- some_data.html
    |   |-- __init__.py
    |   |-- submodule
    |   |   `-- __init__.py
    |   |-- helpers.py
    |-- tests
    |   |-- __init__.py
    |   |-- test_helpers.py
    |-- Makefile
    |-- CHANGES.txt
    |-- LICENSE.txt
    |-- README.md
    |-- requirements-dev.txt
    |-- requirements.txt
    `-- setup.py

输入命令cat Makefile

    PYTHON=`which python`
    NAME=`python setup.py --name`


    all: check test source deb

    init:
        pip install -r requirements.txt --use-mirrors

    dist: source deb

    source:
        $(PYTHON) setup.py sdist

    deb:
        $(PYTHON) setup.py --command-packages=stdeb.command bdist_deb

    rpm:
        $(PYTHON) setup.py bdist_rpm --post-install=rpm/postinstall --pre-uninstall=rpm/preuninstall

    test:
        unit2 discover -s tests -t .
        python -mpytest weasyprint

    check:
        find . -name \*.py | grep -v "^test_" | xargs pylint --errors-only --reports=n
        # pep8
        # pyntch
        # pyflakes
        # pychecker
        # pymetrics

    clean:
        $(PYTHON) setup.py clean
        rm -rf build/ MANIFEST dist build my_program.egg-info deb_dist
        find . -name '*.pyc' -delete

2
你好,Vitaly!我刚刚发现了你的项目。你还在维护它吗?谢谢! - Elias Dorneles
2
最终出现了404错误。 - Dimitrios Mistriotis
2
链接 https://github.com/vital-fadeev/python-package-template 已失效。请问这个 python-package-template 可以在哪里找到? - Toothpick Anemone

13

8
在决定项目结构之前,最好先问自己这个项目的目的是什么。这是一次性分析吗?你想要探索的玩具概念?还是你打算分发的完整项目?你想要投入多少精力来构建项目结构也会有所不同。
  • If it's a one off analysis, I like to use ipython notebooks. The notebook will capture the flow of your thoughts, and you can add notes in markup to your code for later reference.
  • If it's a toy concept you want to investigate, I find a simple, quick approach to work best. You want to be able to quickly implement your concept to discover if it's even feasible and thus worth spending more time on it. Part of Python's philosophy is 'Don’t try for perfection because “good enough” is often just that.' You can always come back later and structure your project in a way that follows best software engineering practices.
  • If you want to structure your project so you can later distribute it, and so that it scales to many modules I recommend the following structure:

    projectname
     ├── MANIFEST.in
     ├── setup.py
     ├── README
     ├── .gitignore
     ├── .git
     ├── projectname_env
     └── projectname
         ├── __init__.py
         ├── subpackageone
         │   ├── __init__.py
         │   ├── second_module.py
         │   ├── tests
         │   │   └── test_second_module.py
         │   └── models
         │       └── model1
         ├── first_module.py   
         └── tests
             └── test_second_module.py
    

我喜欢这种结构的详细原因在我的博客文章中,但基本要点是层级较低的projectname目录包含了你的实际项目。与之并列的是所有帮助管理(git)和打包(setup.py、MANIFEST.in)的工具。


你会如何运行你的项目?在根目录下执行 python3 -m 项目名称 吗? - buhtz

4
一个包是一个带有__init__.py文件的目录。与目录的区别在于,您可以导入它。
虽然没有一种“Python方式”,但您会发现将所有模块放在一个与项目相关的名称的包中是一个好主意。
此外,为了遵循Python风格指南PEP8,包和模块名称应全部小写。因此,如果我们假设项目名为“Botond Statistics”,则你的结构将如下所示:
botondstats/
    indicators/
        moving_averages.py
        stochastics.py
    strategies/
        moving_averages_cross.py
    example.py

通过执行以下操作,您将找到随机指标类:

from botondstats.indicators.stochastics.Stochastics

有许多方法可以保持结构,但使导入更短,但这是另一个问题。

如果您愿意,您可以将此结构放在 src / 下,但这并不是必要的。我从不这样做。 相反,我有一个主目录:

BotondStatistics/
    docs/
    botonstats/ # the above structure
    setup.py    # Distutils/distribute configuration for packaging.

在这个目录中,我通常也有一个虚拟环境,因此我也有bin/ lib/等文件夹。开发通常通过运行以下命令完成:

./bin/python setup.py tests

当我使用Distrubute测试运行器来运行测试时。

这就是我做的方式。:-)


3

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接