如何让两个脚本引用同一个模块

时间:2015-05-05 19:56:27

标签: python python-2.7

我正在编写两个旨在从命令行运行的脚本。我们称他们为foo.pybar.py。另外,我有一个名为util的实用程序模块,它将由这两个脚本共享。如何构建代码,以便foobar都可以使用import util之类的简单行?目前,我的目录结构如下:

MyProject
\--foo
   \--foo.py
   \--foo_util.py
\--bar
   \--bar.py
   \--bar_util.py
\--util
   \--util.py

foo内,我希望能够写import foo_utilimport util,但我不会这样做。希望能够写import bar,因为它们是独立的程序,没有理由彼此使用'代码。

更新:chepner解决方案的略微修改版本,我发现了一些似乎对我有用的东西。我的项目现在结构如下:

MyProject
   \--__init__.py
   \--foo.py
   \--bar.py
   \--MyProject
      \--__init__.py
      \--foo
         \--__init__.py
         \--foo_impl.py
      \--bar
         \--__init__.py
         \--bar_impl.py
      \--shared
         \--__init__.py
         \--util.py

foo.py可以写import MyProject.foo as foobar.py可以做类似的事情,而foobar都可以import MyProject.shared

4 个答案:

答案 0 :(得分:3)

我建议采用以下布局:foo.pybar.py作为脚本,可以放在任何地方。您应该在已知位置安装以下包:

<known location, such as /usr/lib/python/site-packages>
\--foo
   \--util.py
\--bar
   \--util.py
\--util.py

然后,使用import foo.utilimport bar.utilimport util在必要的时间和地点访问各个模块。

正如abarnert指出的那样,你无法隐藏bar/util.py foo,也不关心这样做。

答案 1 :(得分:0)

util放入site-packages。这就是你希望能够import进入多个项目的任何模块应该去的地方。

答案 2 :(得分:0)

import util,根据您当前的结构,不会导入您的util:它导入Python的util模块。要解决这个问题,你必须将__init__.py添加到util目录,这使它成为有效的Python包。

为了导入你的util,你可以做相对导入(这会违反你的第二个愿望,甚至要求你的应用程序成为一个包)或使用PYTHONPATH来运行你的脚本。

PYTHONPATH="../util" python foo.py

如果您想将util用作库,它属于site-packages目录,隐含位于PYTHONPATH

答案 3 :(得分:0)

我认为你在这里缺少的是构建一个可安装的基于setuptools的软件包解决了你的问题,而实际上并没有要求你在系统范围内安装任何东西

首先,这种事情正是为virtualenv创建的。 (或者,如果您使用的是3.4+,那么stdlib的venv。)您可以创建一个新的虚拟环境。在该环境中,您pip install .util库,现在它位于该环境的site-packages中。然后,您可以在该环境中运行foobar以及其他任何内容,并且它们都可以import util - 但您的主系统环境中没有任何变化。

即使您出于某种原因不想使用virtualenv(但您确实应该......),如果您正确构建设置,它将允许您以“开发”模式运行所有内容,伪造安装到源树下的目录,并设置所有链接以使其工作。当您尝试安装多个单独的脚本以及它们共享的模块时,这可能有点繁琐,但它确实有效。

关于如何布局分布的完整教程,让setuptools自动生成包装器脚本并将它们安装到bin等等,对于这里的答案来说太大了,PyPA人{ {3}}。有一些复杂的部分,所以你可能会在某些时候陷入困境,但是当你这样做时,你会有另一个好问题要问SO。 :)