Sublime Text 3 创建插件添加外部 python 库

Sublime Text 3 Creating Plugin adding external python libraries

所以我正在尝试创建一个插件并使用上下文菜单执行它。在我的插件中,我想使用机械汤模块。

我已按如下方式配置 Context.sublime-menu 文件以创建上下文菜单选项:

[
{
    "id": "SlackSnippets",
    "caption": "SlackSnippets",
    "children":
    [
        {"id": "wrap"},
        { "command": "slacksnippet" }
    ]
}
]

现在,有了这个,上下文菜单的极端基本功能就可以工作了,它会在您右键单击时显示,并且它的子命令是可单击的: .

但是,我 运行 遇到麻烦的地方是当我尝试在定义 'SlackSnippet' 命令的 python 文件中导入机械汤模块时:

from __future__ import print_function
import os
import mechanicalsoup """If Commented out, I can click the command in the context window"""
import sublime
import sublime_plugin


class SlacksnippetCommand(sublime_plugin.TextCommand):

    def run(self, edit):
        ## Code

然后上下文菜单中的命令变灰,我无法使用它:

我是在 Sublime Text 3 中创建插件的新手,如有任何帮助,我将不胜感激!

你的命令在第二种情况下变灰的原因是因为 Sublime 无法使用你提到的行加载插件,因此它不知道菜单项告诉它的命令执行,因此它被禁用(如果您使用命令面板,在这种情况下该命令根本不会出现)。

如果您使用 Ctrl+`View > Show Console 打开 Sublime 控制台,您将看到一个堆栈跟踪:

ImportError: No module named 'mechanicalsoup'

首先要注意的是,Sublime Text 包含它自己的 Python 3.3.6 嵌入式版本,它与您可能安装在计算机上的任何 Python 版本完全不同。

因此默认情况下无法加载系统安装的 Python 模块,因为它对它们一无所知。可以让 Sublime 查看系统位置,但这通常不是一个好主意,因为它引入了很多外部依赖项,你的 plugin/package 用户需要在你的代码运行之前安装这些依赖项(包括安装 Python 3.3.6 本身)。

一般来说,嵌入在 Sublime 中的 Python 解释器会在几个位置寻找 Python files/modules,但唯一供用户交互的位置是:

  1. Sublime Text Packages 文件夹,您可以通过从菜单中选择 Preferences > Browse Packages 进入该文件夹
  2. 一个名为 Lib/python3.3 的文件夹(LibPackages 文件夹存储在同一位置;使用该命令并向上一级文件夹)

您可以选择将模块(例如 mechanicalsoup 放在 Packages 文件夹中。但是,这不是一个特别好的主意,因为 Sublime 会尝试加载顶层 Python 源文件自动(因为它认为它是一个包)这不是你想要的,除非在简单的情况下,否则实际上可能不起作用。

Sublime 忽略任何不在包文件夹顶层的 Python 文件,除非你明确告诉它加载它(即通过 import)。因此,您可以将模块直接放在包文件夹中,然后从那里导入它们。

例如,如果您的包名为 SlackSnippets,您的包文件夹可能如下所示:

SlackSnippets/
|-- mechanicalsoup
|   |-- __init__.py
|   |-- __version__.py
|   |-- browser.py
|   |-- form.py
|   |-- stateful_browser.py
|   `-- utils.py
`-- slack_snippet_cmd.py

现在可以通过指定模块名称导入模块SlackSnippets.mechanicalsoup:

from __future__ import print_function
import os
import SlackSnippets.mechanicalsoup 
import sublime
import sublime_plugin


class SlacksnippetCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        pass

(注意: 这还是不行,因为这个模块需要安装其他模块,比如requests。我不确定那有多深但是,由于我不使用此模块,所以特定的兔子洞会消失。)

根据所讨论的模块及其编写方式,以这种方式工作可能涉及更多工作,例如是否需要特定于操作系统的库。

这给我们留下了上面提到的第二个选项,即将您的模块放在 Lib/python3.3 文件夹中,以便 Sublime 能够找到它们。

在这种情况下,由于该文件夹在搜索路径中,您最初发布的代码将加载模块而无需任何更改(尽管由于没有 requests 模块可用,它仍然无法在此处工作) .

不过,您(和您的用户)仍然有责任将模块放在那里; Sublime 不会自己为你做那种事情。如果您计划在完成后使用包控制来分发您的包,您可以从中得到一点喘息的机会。

Package Control 支持 dependency modules 的概念,并通过一些设置在安装包时为用户安装模块(如果尚未安装)。

目前这是由 Package Control 处理的,方法是将模块放入具有特殊包布局的 Packages 文件夹,然后在幕后做一些工作,以便 Sublime 将其视为常规模块。

为了使其正常工作,您需要将所需的依赖项也存储在包控制中,如果您感兴趣的模块尚不可用,则需要您进行更多设置工作.

目前 mechanicalsoup 不可用,但 requests 可用。可用依赖项列表是 here.