自动调用常用初始化代码,无需创建__init__.py文件

Sup*_*ric 5 python scripting python-module pythonpath

我的项目中有两个目录:

project/
  src/
  scripts/
Run Code Online (Sandbox Code Playgroud)

“src”包含我精心编写的代码,“scripts”包含一次性的 Python 脚本。

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

scripts/__init__.py:
  import sys
  sys.path.append("../src")
Run Code Online (Sandbox Code Playgroud)

这可行,但会产生不必要的副作用,即将我的所有脚本放入名为“scripts”的包中。还有其他方法可以让我的所有脚本自动调用上述初始化代码吗?

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

Gre*_*ins 4

即使您有其他分发计划,也可能值得将基本内容放在setup.py您的src文件夹中。这样,您可以运行setup.py developdistutils 将代码链接放到默认路径上(这意味着您所做的任何更改都将就地反映,而无需“重新安装”,并且所有模块都将“正常工作”,无论在哪里你的脚本是)。这将是一次性步骤,但这仍然比零多一步,因此这取决于这是否比更新更麻烦.bashrc。如果您使用pip,则相当于pip install -e /path/to/src.

更强大的解决方案(特别是如果您要在多个开发人员的计算机上镜像/版本控制这些脚本)是在受控虚拟环境中进行开发工作。事实证明,virtualenv 甚至内置了对自定义引导程序的支持。看起来你只需要一个after_install()钩子来调整sitecustomize、运行pip install -e或将纯.pth文件添加到站点包中。自定义引导程序可以与其他脚本一起存在于源代码管理中,并且需要为每个开发人员的设置运行一次。您还可以获得使用 virtualenv 的正常好处(显式依赖版本控制、与系统范围配置的隔离以及不同计算机之间的标准化等)。

如果您确实不想进行任何设置步骤并且愿意仅从__init__.py“项目”目录内部运行这些脚本,那么您可以像这样输入:

project/
    src/
        some_module.py
    scripts/
        __init__.py # special "magic"
        some_script.py
Run Code Online (Sandbox Code Playgroud)

您的文件可能如下所示:

# 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'))
Run Code Online (Sandbox Code Playgroud)

然后你必须像这样运行你的脚本:

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

谨防!脚本只能从内部这样调用project/

[~/otherdir] $ python -m scripts.some_script
ImportError: no module named scripts
Run Code Online (Sandbox Code Playgroud)

要启用此功能,您需要返回编辑.bashrc或使用上述选项之一。最后一个选择确实应该是最后的手段;正如@Simon 所说,那时你真的在与语言作斗争。