自动调用公共初始化代码而不创建__init__.py文件

时间:2011-08-30 22:40:18

标签: python scripting python-module pythonpath

我的项目中有两个目录:

project/
  src/
  scripts/

“src”包含我的优秀代码,“脚本”包含一次性Python脚本。

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

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

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

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

3 个答案:

答案 0 :(得分:3)

即使您有其他分发计划,也可能值得在src文件夹中组合一个基本的setup.py。这样,您就可以运行setup.py develop让distutils将链接放到您的默认路径上(这意味着您所做的任何更改都会在不必“重新安装”的情况下就地反映出来,并且所有模块都将“正常工作”,无论您的脚本在哪里)。这是一次性步骤,但这仍然是零步骤,所以这取决于是否比更新.bashrc更麻烦。如果您使用pip,则等效值为pip install -e /path/to/src

更强大的解决方案 - 特别是如果您要在多个开发人员的计算机上镜像/版本化这些脚本 - 就是在受控的虚拟环境中进行开发工作。事实证明virtualenv甚至内置了support for making your own bootstrap customizations。您似乎只需要一个after_install()挂钩即可调整sitecustomize,运行pip install -e或向网站包添加普通.pth文件。自定义引导程序可以与其他脚本一起存在于源代码管理中,并且需要为每个开发人员的设置运行一次。您还可以使用virtualenv(显式依赖版本控制,与系统范围配置隔离以及不同机器之间的标准化等)的正常优势。仅举几例。

如果您确实不希望任何设置步骤并且愿意从'project'目录中运行这些脚本,那么您可以在__init__.py中如此:

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

这些是您的文件的样子:

# 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'))

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

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

小心!这些脚本只能 project/内部

进行调用。

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

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

答案 1 :(得分:0)

如果您希望脚本可以运行(我假设从命令行开始),那么它们必须位于某个路径上。

但是你想要做的事情听起来很奇怪。你能告诉我们一个你要完成什么的例子吗?

答案 2 :(得分:0)

你可以在项目目录中添加一个名为'pathHack.py'的文件,并将其放入其中:

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

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

开始
import pathHack

现在你可以从脚本dir导入东西,而不需要'脚本'。字首。如果此目录中只有一个文件,并且您不关心隐藏此类内容,则可以内联此代码段。