我在一个相当标准化的目录结构中对不同的项目(我是一名科学家)做了很多工作.例如:
project
/analyses/
/lib
/doc
/results
/bin
Run Code Online (Sandbox Code Playgroud)
我将所有各种实用程序脚本放在/ bin /中,因为清洁度与敬虔相关.但是,我必须硬编码路径(例如../../x/y/z)然后我必须在./bin/中运行它们或者它们会中断.
我已经使用了Django,它有/manage.py运行各种django-things并自动处理路径.我还使用了fabric来运行各种用户定义的函数.
问题:我该如何做类似的事情?什么是最好的方式?我可以很容易地在/manage.py中写一些内容来将root目录注入sys.path等,但是我希望能够执行"./manage.py foo"运行/bin/foo.py.或者是否可以让Fabric从某个目录中调用可执行文件?
基本上 - 我想要一些简单和低维护的东西.我希望能够将可执行脚本/文件/删除到./bin/中,而不必处理路径问题或导入问题.
做这个的最好方式是什么?
通常,尝试将运行时保持在顶级.这将极大地理顺您的进口.
如果你必须使用相对导入进行大量的导入寻址,那么可能有更好的方法.
其他海报都提到了PYTHONPATH.这是在shell中永久执行它的好方法.
如果你不想/不能PYTHONPATH直接操纵项目路径,你可以sys.path用来让自己脱离相对导入的地狱.
sys.path.appendsys.path只是内部列表.您可以附加到其中以添加内容到您的路径中.
说我在/bin这里面的库markdown中lib/.您可以附加相对路径sys.path以导入所需内容.
import sys
sys.path.append('../lib')
import markdown
print markdown.markdown("""
Hello world!
------------
""")
Run Code Online (Sandbox Code Playgroud)
明智的话:不要对你的sys.path添加过于疯狂.保持您的架构简单,以避免自己很多混乱.
过于急切的导入有时会导致python模块需要自行导入的情况,此时执行将停止!
__init__.py另一个很棒的技巧是通过添加__init__.py文件来创建python包. __init__.py在目录中的任何其他模块之前加载,因此这是在整个目录中添加导入的好方法.这使它成为添加sys.pathhackery 的理想场所.
您甚至不需要向文件添加任何内容.只需touch __init__.py在控制台上创建一个包就可以了.
在当前 shell 中获取(而不是运行)的 shell 脚本中,设置以下环境变量:
PATH=$PATH:$PROJECTDIR/bin
PYTHONPATH=$PROJECTDIR/lib
Run Code Online (Sandbox Code Playgroud)
然后将 Python 模块和包树放入项目的 ./lib 目录中。Python 自动将 PYTHONPATH 环境变量添加到sys.path.
然后,您可以从 shell 运行任何顶级脚本,而无需指定路径,并且会在 lib 目录中查找来自库模块的任何导入。
我推荐非常简单的顶级脚本,例如:
#!/usr/bin/python
import sys
import mytool
mytool.main(sys.argv)
Run Code Online (Sandbox Code Playgroud)
然后您就不必更改它,只需编辑模块代码即可,并且还可以从字节码缓存中受益。
| 归档时间: |
|
| 查看次数: |
4482 次 |
| 最近记录: |