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

发布于 2024-12-01 23:24:36 字数 496 浏览 3 评论 0原文

我的项目中有两个目录:

project/
  src/
  scripts/

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

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

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

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

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

I have two directories in my project:

project/
  src/
  scripts/

"src" contains my polished code, and "scripts" contains one-off Python scripts.

I would like all the scripts to have "../src" added to their sys.path, so that they can access the modules under the "src" tree. One way to do this is to write a scripts/__init__.py file, with the contents:

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

This works, but has the unwanted side-effect of putting all of my scripts in a package called "scripts". Is there some other way to get all my scripts to automatically call the above initialization code?

I could just edit the PYTHONPATH environment variable in my .bashrc, but I want my scripts to work out-of-the-box, without requiring the user to fiddle with PYTHONPATH. Also, I don't like having to make account-wide changes just to accommodate this one project.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

水溶 2024-12-08 23:24:36

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

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

如果您真的不想进行任何设置步骤并且愿意从“项目”目录中运行这些脚本,那么您可以在< code>__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 所说,那时你真的在与语言作斗争。

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.

伴梦长久 2024-12-08 23:24:36

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

不过,您正在尝试做的事情听起来有些奇怪。您能向我们展示一个您想要实现的目标的示例吗?

If you want your scripts to be runnable (I assume from the command line), they have to be on the path somewhere.

Something sounds odd about what you're trying to do though. Can you show us an example of exactly what you're trying to accomplish?

浅黛梨妆こ 2024-12-08 23:24:36

您可以在项目目录中添加一个名为“pathHack.py”的文件,然后将类似的内容放入其中:

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

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

import pathHack

现在您可以从脚本目录中导入内容,而无需使用“脚本。前缀。如果此目录中只有一个文件,并且您不关心隐藏此类内容,则可以内联此代码片段。

You can add a file called 'pathHack.py' in the project dir and put something like this into it:

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

Then, in a python file in your project dir, start by:

import pathHack

And now you can import stuff from the scripts dir without the 'scripts.' prefix. If you have only one file in this directory, and you don't care about hiding this kind of thing, you may inline this snippet.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文