我正在尝试将我的Python代码放入用于部署的标准目录结构中setup.py,也许是PyPI.对于一个名为mylib的Python库,它将是这样的:
mylibsrc/
README.rst
setup.py
bin/
some_script.py
mylib/
__init.py__
foo.py
Run Code Online (Sandbox Code Playgroud)
通常还有一个test/子目录,但我还没有尝试编写单元测试.bin/可以在官方Python打包文档中找到在子目录中包含脚本的建议.
当然,脚本的开头代码如下所示:
#!/usr/bin/env python
from mylib.foo import something
something("bar")
Run Code Online (Sandbox Code Playgroud)
当它最终部署脚本(例如devpi)然后用pip安装它时,这很有效.但是,如果我直接从源目录运行脚本,就像我在开发库/脚本的新更改时一样,我收到此错误:
ImportError: No module named 'mylib'
Run Code Online (Sandbox Code Playgroud)
即使当前工作目录是root mylibsrc/并且我通过键入运行脚本也是如此./bin/some_script.py.这是因为Python开始在正在运行的脚本(即from bin/)的目录中搜索包,而不是当前的工作目录.
什么是一种好的,永久性的方法,可以在开发包时轻松运行脚本?
这是一个相关的其他问题(特别是对第一个答案的评论).
到目前为止,我发现的解决方案分为三类,但没有一个是理想的:
mylibsrc到我的PYTHONPATH环境变量.这似乎是最官方的(Pythonic?)解决方案,但意味着每次我检查一个项目时我都要记得在我可以运行其中的任何代码之前手动更改我的环境..到我的PYTHONPATH环境变量的开头.据我了解,这可能会有一些安全问题.如果我是唯一一个使用我的代码的人,这实际上是我最喜欢的技巧,但我不是,我不想让别人这样做.test/我看到了他们所有(间接)包含一行代码的建议sys.path.insert(0, os.path.abspath('..'))(例如,在构建项目时).呸!对于仅用于测试的文件而言,这似乎是一个可以忍受的黑客攻击,而不是那些随软件包一起安装的文件.-m脚本运行脚本,搜索路径在工作目录而不是bin/目录中开始.有关详细信息,请参阅下面的答案.setup.py developlogc答案和pip install -e我的命令.他们避免为每一个小编辑重新"安装",但你仍然需要创建一个setup.py你永远不打算完全安装的包,并且与PyCharm(它有一个菜单项来运行develop命令但不能很好地工作)没有简单的方法来运行它复制到虚拟环境的脚本.mylibsrc/代替mylibsrc/bin/).
自从我发布这个问题以来,我了解到您可以使用 Python 的-m命令行开关(我原以为只适用于包)来运行模块,就好像它是脚本一样。
所以我认为最好的解决方案是这样的:
if __name__ == "__main__": main(),就像在脚本中一样。python -m pkg_name.module_namePyCharm 不支持以这种方式运行模块(请参阅此请求)。但是,您可以像平常一样运行模块(以及 bin 中的脚本),因为 PyCharm 会自动将项目根添加到 PYTHONPATH,因此导入语句无需任何进一步的努力即可解析。不过,这有一些问题:
from pkg_name.other_module import fn但不能做from .other_module import fn。无论如何,相对导入通常都是糟糕的风格,但它们对于单元测试很有用。pkg_name.module_name,一次为 as __main__)。但无论如何你不应该有循环依赖。额外的命令行乐趣:
bin/你可以使用它们来调用它们python -m bin.scriptname(但在Python 2中你需要将一个放在__init__.pybin目录中)。__main__.py,如下所示:python -m pkg_name命令行还有一个替代方案,它并不那么简单,但仍然值得了解:
pip install -e . pip uninstall pkg_namesetup.py这与的命令类似develop,但卸载似乎效果更好。| 归档时间: |
|
| 查看次数: |
2013 次 |
| 最近记录: |