5

我的项目中有两个目录:

project/
  src/
  scripts/

“src” 包含我完善的代码,“scripts” 包含一次性 Python 脚本。

我希望所有脚本都将“../src”添加到它们的 sys.path 中,以便它们可以访问“src”树下的模块。一种方法是编写一个 scripts/__init__.py 文件,其内容为:

scripts/__init__.py:
  import sys
  sys.path.append("../src")

这可行,但有将我的所有脚本放在一个名为“脚本”的包中的不良副作用。还有其他方法可以让我的所有脚本自动调用上述初始化代码吗?

我可以在我的 .bashrc 中编辑 PYTHONPATH 环境变量,但我希望我的脚本可以开箱即用,而不需要用户摆弄 PYTHONPATH。此外,我不喜欢仅仅为了适应这个项目而对整个帐户进行更改。

4

3 回答 3

4

Even if you have other plans for distribution, it might be worth putting together a basic setup.py in your src folder. That way, you can run setup.py develop to have distutils put a link to your code onto your default path (meaning any changes you make will be reflected in-place without having to "reinstall", and all modules will "just work," no matter where your scripts are). It'd be a one-time step, but that's still one more step than zero, so it depends on whether that's more trouble than updating .bashrc. If you use pip, the equivalent would be pip install -e /path/to/src.

The more-robust solution--especially if you're going to be mirroring/versioning these scripts on several developers' machines--is to do your development work inside a controlled virtual environment. It turns out virtualenv even has built-in support for making your own bootstrap customizations. It seems like you'd just need an after_install() hook to either tweak sitecustomize, run pip install -e, or add a plain .pth file to site-packages. The custom bootstrap could live in your source control along with the other scripts, and would need to be run once for each developer's setup. You'd also have the normal benefits of using virtualenv (explicit dependency versioning, isolation from system-wide configuration, and standardization between disparate machines, to name a few).

If you really don't want to have any setup steps whatsoever and are willing to only run these scripts from inside the 'project' directory, then you could plop in an __init__.py as such:

project/
    src/
        some_module.py
    scripts/
        __init__.py # special "magic"
        some_script.py

And these are what your files could look like:

# file: project/src/some_module.py
print("importing %r" % __name__)

def some_function():
    print("called some_function() inside %s" % __name__)
--------------------------------------------------------
# file: project/scripts/some_script.py
import some_module

if __name__ == '__main__':
    some_module.some_function()
--------------------------------------------------------
# file: project/scripts/__init__.py
import sys
from os.path import dirname, abspath, join

print("doing magic!")
sys.path.insert(0, join(dirname(dirname(abspath(__file__))), 'src'))

Then you'd have to run your scripts like so:

[~/project] $ python -m scripts.some_script
doing magic!
importing 'some_module'
called some_function() inside some_module

Beware! The scripts can only be called like this from inside project/:

[~/otherdir] $ python -m scripts.some_script
ImportError: no module named scripts

To enable that, you're back to editing .bashrc, or using one of the options above. The last option should really be a last resort; as @Simon said, you're really fighting the language at that point.

于 2011-08-31T16:05:36.943 回答
1

您可以在项目目录中添加一个名为 'pathHack.py' 的文件,并在其中放入如下内容:

import os
import sys
pkgDir = os.path.dirname(__file__)
sys.path.insert(os.path.join(pkgDir, 'scripts')

然后,在项目目录中的 python 文件中,开始:

import pathHack

现在您可以从脚本目录中导入内容,而无需使用“脚本”。字首。如果你在这个目录中只有一个文件,并且你不关心隐藏这种东西,你可以内联这个片段。

于 2011-08-31T15:23:36.493 回答
1

如果您希望您的脚本可运行(我假设从命令行),它们必须在某处的路径上。

不过,您尝试做的事情听起来有些奇怪。您能否向我们展示一个您正在尝试完成的具体示例?

于 2011-08-30T23:19:53.943 回答