2017-10-12 74 views
2

我有一个python应用程序(基于Django),我有几个独立的维护脚本与应用程序一起使用,我必须不时地调用它。他们必须导入我的应用程序的一部分(子包)。目前,我只是把它们放在我的顶层目录:python应用程序中的脚本目录的成语?

application/ 
    djangoproject/ 
    djangoapp/ 
    otherpackage/ 
    tool1.py 
    tool2.py 

tool1.py会做

from djangoproject import wsgi 
from djangoapp.models import Poll 

我已经积累了相当一些工具,并想将其移动到一个scripts子目录。然后,我希望能够通过python scripts/tool1.py或者cd scripts; python tool1.py给他们打电话。

我明白(有时候会哀叹)Python的导入是如何工作的,而且我知道我可以在每个脚本中添加一些行来将父目录添加到PYTHONPATH。我想知道是否有广泛的模式来处理这样的各种脚本集合。也许可以将路径操作放到另一个文件中,并且每个脚本都以import mainproject开头?

我正在使用virtualenv,并使用pip安装依赖项。但是应用程序本身目前不使用setup.py,我认为将脚本移动到通过pip安装的单独程序包是无济于事的,因为在开发过程中我经常对它们进行更改,并且有很多一次性操作。

+2

如果这些脚本正在为您的django应用程序做些什么,您可以考虑编写[自定义管理命令](https://docs.djangoproject.com/en/1.11/howto/custom-management-commands/)。你也可以把这些脚本放在他们自己的package /目录中,并将该目录添加到你的venv激活脚本中的env PATH变量中。 – schwobaseggl

回答

1

组织源代码的方法因项目而异。从我多年的经验来看,最好的和最pythonic的方式是始终有setup.py

在这种情况下,您可以将pip install -e .editable version. dir虚拟安装到virtualenv。其实,并没有真正安装(即复制),但“链接”:源代码目录将被添加到sys.path.pth文件,所以你可以编辑&尝试没有任何特殊的复制/安装步骤。

更多相关内容,您可以通过将extra dependencies扩展为例如开发目的,并通过pip install -e .[dev]安装。更像是一种奇特的后果。

其余取决于脚本的性质。


如果脚本是应用程序的一部分,则应通过entry-points in setup.py进行安装。

# setup.py: 
setup(
    entry_points={ 
     'console_scripts': [ 
      'tool1 = mytools.tool1:main', 
      'tool2 = mytools.tool2:main', 
     ], 
    }, 
) 

在这种情况下,后pip install -e .,它们将在virtualenv中的bin文件夹,或在/usr/local/bin或类似物,如果系统蟒被使用。你可以这样执行它们:

source .venv/bin/activate 
tool1 ... 

# OR: 

~/path/to/venv/bin/tool2 

脚本安装这种方式充分了解virtualenv中,他们被安装到,因此不需要激活,并没有明确的蟒蛇二进制文件。


如果脚本是用于代码维护,而不是应用程序的语义部分,然后它们通常在顶部(#!/usr/bin/env python)投入./scripts/目录(或任何其他例如./ci/)中,用家当。例如,tool1.py

#!/usr/bin/env python 
def main(): 
    pass 
if __name__ == '__main__': 
    main() 

,并按如下当前的virtualenv由于这个家当执行:

source .venv/bin/activate 
./scripts/tool1.py ... 

# OR: 

~/path/to/venv/bin/python ./scripts/tool1.py 

与通过入口点安装的脚本,这些脚本不知道在自己的virtualenv任何方式,所以virtualenv应该是激活或适当的python明确使用。

当脚本是非python的时候,例如,为bash脚本。


在这两种情况下,requirements.txt文件有时被用来应用程序的&依赖版本(与pip freeze),这样的部署将持续&预测的。但这是另一个故事 - 关于应用程序的部署,而不是关于维护的包装&。

requirements.txt文件经常重新生成以满足setup.py中新的未固定(即灵活)要求和新的可用软件包版本。但通常它是生成的内容(尽管在回购中承诺),而不是手动维护的内容。


如果严格不想有setup.py以任何理由,那么无论用修改的环境变量执行这些脚本:

PYTHONPATH=. python scripts/tool1.py 

或者破解sys.path从里面:

# tools1.py 
import sys 
import os 
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) 

这正是pip install -e .所做的,只是在每次调用时手动完成,而不是在vi中使用.pth文件rtualenv。而且这看起来很黑。

但是,正如我们所知,无论是hacky解决方案还是重复解决方案,尤其是那些复制标准工具包的解决方案,都被认为是“pythonic”。