为什么有些 Python 包有重复的目录名?

Why do some Python packages have repetitive directory names?

关于 Python 项目的目录结构的问题已在 Stack Overflow 上多次被问到(例如 here, and

并且给出了很多答案。但是在任何这些答案中似乎都不清楚的一件事是为什么有些项目有重复的目录。比如经常被引用的this article中,建议的布局是:

<root>/
|-- Twisted/    
|   |-- __init__.py
|   |-- README
|   |-- setup.py
|   |-- twisted/ 
|   |   |-- __init__.py
|   |   |-- main.py
|   |   |-- test/   
|   |   |   |-- __init__.py
|   |   |   |-- test_main.py
|   |   |   |-- test_other.py
|   |   |-- bin/
|   |   |   |-- myprogram

在此示例中,/Twisted/twisted/main.py 是主文件

但是另一方面你有建议like this:

Many developers are structuring their repositories poorly due to the new bundled application templates.

<root>/
|-- samplesite/
|   |-- manage.py  
|   |-- samplesite/
|   |   |-- settings.py
|   |   |-- wsgi.py   
|   |   |-- sampleapp/
|   |   |-- models.py

Dont do this.

Repetitive paths are confusing for both your tools and your developers. Unnecessary nesting doesnt help anybody. Let's do it properly:

<root>/
|-- manage.py  
|-- samplesite/
|   |-- settings.py
|   |-- wsgi.py   
|   |-- sampleapp/
|   |-- models.py

我的问题不一定是"which way is better?",因为每种方式都可能有利有弊。

相反,我的问题是,如果我采用更简化的第二种样式,我会失去什么?有充分的理由拥有 /<root>/Twisted/twisted/main.py 目录结构而不仅仅是 /<root>/twisted/main.py 吗?是否可以更轻松地共享我的应用程序或使 import 流程更顺畅?还有别的吗?

我相信 python 项目最常见的布局是这样的:

project/
|-- setup.py
|-- bin/
|-- docs/ ...
|-- examples/ ...
|-- package/
    |-- __init__.py
    |-- module1.py
    |-- module2.py
    |-- subpackage/ ...
    |-- tests/ ...

其中project是项目的名称,package是顶级import的名称,例如scikits-learn和sklearn。该包包含 python 应该能够导入的所有内容,您可以使用包名称导入。例如 from package import thingfrom package.module1 import thing。该项目有包和任何支持的东西,如文档、示例和安装脚本。请注意,项目中通常没有 __init__.py,因为项目不可 python 导入。项目和包同名很常见,但不是必须的。

这两份文件比你想象的要近。 Interesting Things, Largely Python and Twisted Related (your first example) and the django-admin startproject docs assume you are outside of the project repository while Structuring Your Project (您的第二个示例)都假定您在存储库中。引用一下,"Well, they go to their bare and fresh repository and run the following...".

django 文档声明如果你 运行

django-admin.py start-project samplesite 

both the project directory and project package will be named and the project directory will be created in the current working directory

该命令会为您创建项目目录,因此当您 运行 它时,您当然不应该在已经创建的项目目录中。文档继续说

django-admin startproject myproject /Users/jezdez/Code/myproject_repo 

If the optional destination is provided, Django will use that existing directory as the project directory

现在,假设您已经在 /Users/jezdez/Code/myproject_repo。然后你会做

django-admin startproject myproject .

在当前目录下创建项目包。瞧,你有第二个作者的例子!如果您在 运行 命令之前创建存储库,作者实际上只是告诉您避免使用第一种形式。

所以,让我们重新绘制您的目录结构。在第一个示例中,<root> 是您保存开发存储库的目录。 Twisted 是您的存储库所在的目录。 (顺便说一句,该目录不应该有 __init__.py 因为它不是包目录)。在最后一个示例中,<root> 是 repo 目录本身。假设我将该目录命名为 DjangoExample,那么结构将是

<root>
|-- Twisted/    
|   |-- __init__.py
|   |-- README
|   |-- setup.py
|   |-- twisted/ 
|   |   |-- __init__.py
|   |   |-- main.py
|   |   |-- test/   
|   |   |   |-- __init__.py
|   |   |   |-- test_main.py
|   |   |   |-- test_other.py
|   |   |-- bin/
|   |   |   |-- myprogram
|
|-- DjangoExample/
|   |-- manage.py  
|   |-- samplesite/
|   |   |-- settings.py
|   |   |-- wsgi.py   
|   |   |-- sampleapp/
|   |   |-- models.py

至于其他差异,django 应用程序必须遵循 django 框架规则,而 twised 遵循更通用的 python 包规则。