Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/90.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python项目脚本中处理路径/可执行文件的最佳实践(例如,类似Django';s manage.py或fabric的东西)_Python_Fabric - Fatal编程技术网

在Python项目脚本中处理路径/可执行文件的最佳实践(例如,类似Django';s manage.py或fabric的东西)

在Python项目脚本中处理路径/可执行文件的最佳实践(例如,类似Django';s manage.py或fabric的东西),python,fabric,Python,Fabric,我在一个相当标准化的目录结构中为不同的项目做了很多工作(我是一名科学家)。e、 g: project /analyses/ /lib /doc /results /bin 我把我所有的实用程序脚本都放在/bin/中,因为清洁是仅次于敬虔的。但是,我必须对路径进行硬编码(例如,../../x/y/z),然后我必须在./bin/中运行,否则它们会中断 我使用过Django,它有/manage.py,它运行各种Django东西并自动处理路径。我还使用fabric来运行各

我在一个相当标准化的目录结构中为不同的项目做了很多工作(我是一名科学家)。e、 g:

project
   /analyses/
   /lib
   /doc
   /results
   /bin
我把我所有的实用程序脚本都放在/bin/中,因为清洁是仅次于敬虔的。但是,我必须对路径进行硬编码(例如,../../x/y/z),然后我必须在./bin/中运行,否则它们会中断

我使用过Django,它有/manage.py,它运行各种Django东西并自动处理路径。我还使用fabric来运行各种用户定义的函数

问题:我如何做类似的事情?最好的办法是什么?我可以很容易地在/manage.py中编写一些东西,将根目录注入sys.path等,但是我希望能够执行“/manage.py foo”,它将运行/bin/foo.py。或者可以让结构从某个目录调用可执行文件吗

基本上-我想要一些简单和低维护。我希望能够将可执行脚本/文件/任何内容放入./bin/中,而不必处理路径问题或导入问题


执行此操作的最佳方法是什么?

在当前shell中源代码(未运行)的shell脚本中,设置以下环境变量:

PATH=$PATH:$PROJECTDIR/bin
PYTHONPATH=$PROJECTDIR/lib
然后将Python模块和包树放在projects./lib目录中。Python会自动将PYTHONPATH环境变量添加到
sys.path

然后,您可以从shell运行任何顶级脚本,而无需指定路径,并且在lib目录中查找从库模块导入的任何内容

我推荐非常简单的顶级脚本,例如:

#!/usr/bin/python

import sys
import mytool

mytool.main(sys.argv)

然后,您就不必更改它,只需编辑模块代码,还可以从字节码缓存中获益

通过创建一个包含每个项目的迷你包,您可以轻松实现目标。用于创建简单的项目骨架。要使其可执行,只需通过
setup.py develope
安装即可。现在,您的bin脚本只需要将入口点导入此包并执行它。

在TLD处保持执行 一般来说,尽量使运行时保持在顶级。这将大大理顺你的进口

如果您必须使用相对导入进行大量导入寻址,那么可能会有 更好的方法

修改路径 其他海报提到了
PYTHONPATH
。这是一个很好的方法,可以在你的外壳中永久地完成它

如果您不想/无法直接操作
PYTHONPATH
项目路径,您可以使用
sys.path
来摆脱相对导入的困境

使用
sys.path.append
sys.path
只是一个内部列表。您可以附加到它以将内容添加到您的路径中

假设我在
/bin
中,在
lib/
中有一个库
markdown
。您可以使用
sys.path
附加相对路径以导入所需内容

import sys
sys.path.append('../lib')
import markdown


print markdown.markdown("""

Hello world!
------------

""")
对智者说一句话:不要对你的sys.path添加太疯狂。保持你的模式简单以避免你自己的很多困惑

过度急切的导入有时会导致python模块需要导入自身,此时执行将停止

使用软件包和
\uuuuu init\uuuuuuuuuy.py
另一个很好的技巧是通过添加
\uuuu init\uuuu.py
文件来创建python包<代码>\uuuu init\uuuuu.py在目录中的任何其他模块加载之前加载,因此这是跨整个目录添加导入的好方法。这使得它成为添加
sys.path
hackery的理想地点

您甚至不需要向文件中添加任何内容。只需在控制台上执行
触摸_init__.py
即可使目录成为包


举一个更具体的例子。

我只想模仿django的管理功能。py@dm03514说“模仿这个”并链接到400行文件对我来说太不透明了。我不明白你所建议的哪些方面值得效仿。有时候,每个可执行脚本的包似乎都很重。我工作中最大的项目有几十个可执行脚本,它们目前驻留在一个较大的源文件项目中的一个目录中。将所有这些转化为软件包似乎需要更多的工作/复杂性。我是不是太傻了?你是救命恩人。谢谢