Scripts目录是Python中的反模式吗?如果是这样,进口的正确方法是什么?

时间:2014-11-03 22:15:43

标签: python python-2.7

我总是在我构建的每个项目中创建脚本目录,因为它们对于放置不经常使用的可执行脚本非常有用。在Python中,我总是在我的脚本目录中放置__init__.py,这样我就可以将脚本作为包运行(即python -m scripts.some_scripts)并从姐妹目录中加载模块。基于this以及谷歌搜索,我开始觉得这是一种反模式。

那就是说,给出了如下结构:

project_dir/
    some_modules_dir/
        foo.py
        bar.py
        ...
    scripts/
        some_script.py
        other_script.py
        ...

运行脚本的正确方法是什么,以及从姐妹目录some_modules_dir导入脚本的正确方法是什么?哪个目录应该包含__init__.py哪个目录不应该包含{{1}}?我想尽可能地遵循PEP8,并希望尽可能简化运行脚本。如果拥有一个脚本目录本身就是不可取的,那么你们又做了什么呢?

4 个答案:

答案 0 :(得分:4)

问题中的链接仅说明了运行驻留在程序包目录中的脚本 ,这是一个潜在的问题,因为......好...包不是脚本而脚本不是包。它们用于不同的目的,并以不同的方式调用,所以如果你把它们混合在一起,那么在某些时候会变得一团糟。

由于Python 本身已有多个Scripts目录,并且没有人抱怨,所以它绝不是反模式。

请参阅How do I separate my executable files from my library files?,了解我上次职业时处理可执行脚本的方式。它从来没有引起我所知道的任何问题。

答案 1 :(得分:2)

就个人而言,在一个脚本中有一个__init__.py dir感觉有点 off ,但我也可以看到它在这里(以及在IDE中)有用的原因

那就是说,如果他们已经作为Python模块运行,那么他们可能不是真正的脚本,无论是什么甚至意味着(相关:你对这些文件有shebang吗? ?)。很难说没有上下文,但也许他们更接近工具模块,构成整个Python代码库的一部分。

在这种情况下,通过在项目级别添加__init__.py(在您的示例中为project_dir),您可以在您想要的脚本中使用正常导入:

from some_modules_dir import foo

意味着您的原始python -m scripts.some_script使绝对(抱歉)感觉......

答案 2 :(得分:2)

如果你给它一个入口点列表(即main()函数),

Setuptools可以create scripts automatically。如果您已经使用了Setuptools,那么它很容易打开。然后,您可以将scripts目录与其他软件包合并。

答案 3 :(得分:1)

一般来说,如果你的Python项目包含多个项目原生的包,那么应该有一个顶级包,所有其他包都是子包(毕竟它们是同一个项目的一部分,所以那里应该是他们存在的一些统一的理由)。由于目录仅在具有__init__.py时才计为包,另一种说法是,如果项目中的任何两个兄弟目录都有__init__.py,那么他们的父目录应该有一个好。所以假设你有充分的理由拥有一个"脚本"包和一个"模块"直接打包在您的项目根目录中,您很可能拥有,您的项目根目录可能也应该是一个包。

如果您的顶级软件包不是项目根目录,通常认为有一些"松散"与顶级包相邻的Python脚本。像这样:

project_root/
    top_level_package/
        __init__.py
        module.py
        subpackage/
            __init__.py
            anothermodule.py
    adjacent_script.py
    adjacent_script_2.py

"松散"脚本可以直接从包和模块导入,因为它们与顶级包位于同一目录中。这种结构的假设是顶级包包含所有有趣的"您的项目代码(您的"卖点"或者您的项目的#34;肉类"如果您愿意的话),而#34;松散"相邻脚本仅作为您可能希望从顶级包访问的特定功能的入口点。例如,您可能有一个相邻的脚本用于启动测试套件,安装软件,或者如果您的项目是应用程序,则启动应用程序。

关于您的特定模式,我认为您可以区分"脚本"来自" modules"因为脚本是作为您和模块之间的接口。如果它只是你作为开发人员并且你正在使用"脚本"很少,正如你所说,只要根目录有一个__init__.py,就可以坚持你的食谱。但是,如果您(或其他人)也使用"脚本" 作为最终用户,或者如果您经常使用它们,最简单的方法是在顶级软件包旁边提供一个脚本,该脚本捆绑了您的脚本中的功能"单个命令中的目录(或者如果它们提供非常不同的功能,可能是一些命令),每个"脚本"的子命令。您可能希望将argparse标准模块用于该相邻脚本。在任何一种情况下,调用"脚本"可能更合适。 工具

如果您只有几个工具,并且它们不包含除命令行和模块之间的粘合之外的任何代码,您也可以考虑将它们移动到顶层目录。


一些消息来源: