Sublime Text 插件开发中的全局 Python 包

Саш*_*ных 6 python python-3.x sublimetext sublimetext3 sublime-text-plugin

一、总结

\n\n

我不知道 Sublime Text 插件开发人员如何使用 Sublime Text 查找全局 Python 包,而不是 Sublime Text 目录的 Python 包。

\n\n

Sublime Text使用自己的Python环境,而不是机器的Python环境。开发人员需要sys.path设置非内置的 Sublime Text Python 包。

\n\n

是否有任何方法在 Sublime Text 插件中使用全局安装的 Python 包?例如,如果有人告诉我,如何更改我的插件 \xe2\x80\x94 ,那就太好了,请参阅此问题的 3.2 项。

\n\n
\n\n

2.使用Sublime Text 3环境的缺点

\n\n
    \n
  1. Sublime Text 3 Build 3126 使用 Python 3.3,但在撰写此问题时发布了 Python 3.6 稳定版。Python 3.6 有更多功能。
  2. \n
  3. 开发人员需要添加和更新第三方Python包,即使它们是为用户安装的。它花费了开发人员的时间。
  4. \n
  5. 对于开发者来说,可能会遇到包依赖的问题,参见本问题的6.2项。
  6. \n
\n\n
\n\n

3. 示例

\n\n

1.Python代码

\n\n

例如,我将Python代码 \xe2\x80\x94 替换\xd0\x9f\xd0\xbe\xd0\xb8\xd1\x81\xd0\xba \xd0\x9a\xd1\x80\xd0\xb8\xd1\x81\xd1\x82\xd0\xb8\xd0\xbd\xd0\xb8\xd1\x82\xd1\x8b[**\xd0\x9f\xd0\xbe\xd0\xb8\xd1\x81\xd0\xba \xd0\x9a\xd1\x80\xd0\xb8\xd1\x81\xd1\x82\xd0\xb8\xd0\xbd\xd0\xb8\xd1\x82\xd1\x8b**](https://github.com/Kristinita/Kristinita.github.io),其中https://github.com/Kristinita/Kristinita.github.io\xe2\x80\x94 DuckDuckGo 查询的第一个链接\xd0\x9f\xd0\xbe\xd0\xb8\xd1\x81\xd0\xba \xd0\x9a\xd1\x80\xd0\xb8\xd1\x81\xd1\x82\xd0\xb8\xd0\xbd\xd0\xb8\xd1\x82\xd1\x8b

\n\n
# -*- coding: utf-8 -*-\nimport re\nimport urllib\n\nfrom bs4 import BeautifulSoup\n\nfrom w3lib.url import safe_url_string\n\n\n# ASCII link for solved encoding problems \xe2\x80\x94\n# https://stackoverflow.com/a/40654295/5951529\nascii_link = safe_url_string(\n    u\'http://duckduckgo.com/html/?q=\' + \'\xd0\x9f\xd0\xbe\xd0\xb8\xd1\x81\xd0\xba \xd0\x9a\xd1\x80\xd0\xb8\xd1\x81\xd1\x82\xd0\xb8\xd0\xbd\xd0\xb8\xd1\x82\xd1\x8b\',\n    encoding="UTF-8")\nprint(ascii_link)\n# SERP DuckDuckGo\nserp = urllib.request.urlopen(ascii_link)\n# Reading SERP\nread_serp = serp.read()\n# BeautifulSoup \xe2\x80\x94 https://stackoverflow.com/a/11923803/5951529\nparsed = BeautifulSoup(read_serp, "lxml")\n# Parsed first link\nfirst_link = parsed.findAll(\n    \'div\', {\'class\': re.compile(\'links_main*\')})[0].a[\'href\']\n# Remove DuckDuckGo specific characters \xe2\x80\x94\n# https://stackoverflow.com/a/3942100/5951529\nremove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")\n# https://stackoverflow.com/a/32451970/5951529\nfinal_link = (urllib.parse.unquote(remove_duckduckgo_symbols))\n# Markdown link\nmarkdown_link = \'[\' + \'\xd0\x9f\xd0\xbe\xd0\xb8\xd1\x81\xd0\xba \xd0\x9a\xd1\x80\xd0\xb8\xd1\x81\xd1\x82\xd0\xb8\xd0\xbd\xd0\xb8\xd1\x82\xd1\x8b\' + \']\' + \\\n    \'(\' + final_link + \')\'\n\nprint(markdown_link)\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我在终端或 SublimeREPL 中运行此文件,我会得到输出:

\n\n
[**\xd0\x9f\xd0\xbe\xd0\xb8\xd1\x81\xd0\xba \xd0\x9a\xd1\x80\xd0\xb8\xd1\x81\xd1\x82\xd0\xb8\xd0\xbd\xd0\xb8\xd1\x82\xd1\x8b**](https://github.com/Kristinita/Kristinita.github.io/)\n
Run Code Online (Sandbox Code Playgroud)\n\n

2.Sublime Text插件

\n\n

现在,基于这段代码,我编写了 Sublime Text 插件来替换example text[**example text**](http://<first link for DuckDuckGo query \xe2\x80\x9cexample link\xe2\x80\x9d>)

\n\n
[**\xd0\x9f\xd0\xbe\xd0\xb8\xd1\x81\xd0\xba \xd0\x9a\xd1\x80\xd0\xb8\xd1\x81\xd1\x82\xd0\xb8\xd0\xbd\xd0\xb8\xd1\x82\xd1\x8b**](https://github.com/Kristinita/Kristinita.github.io/)\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

4. 预期行为

\n\n

如果用户已经安装了Python并安装了包

\n\n
    \n
  • pip install beautifulsoup4
  • \n
  • pip install lxml
  • \n
  • pip install w3lib
  • \n
\n\n

我希望我的 2.2 项目插件能够成功地为用户工作。

\n\n
\n\n

5. 实际行为

\n\n

如果我保存我的插件,我会得到堆栈跟踪:

\n\n
import re\nimport urllib\n\nfrom bs4 import BeautifulSoup\n\nfrom w3lib.url import safe_url_string\n\nimport sublime_plugin\n\n\nclass KristinitaLuckyLinkCommand(sublime_plugin.TextCommand):\n\n    def run(self, edit):\n        # Get selection text\n        print(\'KristinitaLuckyLink called\')\n        select = self.view.sel()\n        selection_region = select[0]\n        selection_text = self.view.substr(selection_region)\n        print(selection_text)\n\n        # ASCII link for solved encoding problems \xe2\x80\x94\n        # https://stackoverflow.com/a/40654295/5951529\n        ascii_link = safe_url_string(\n            u\'http://duckduckgo.com/html/?q=\' + (selection_text),\n            encoding="UTF-8")\n        print(ascii_link)\n        # SERP DuckDuckGo\n        serp = urllib.request.urlopen(ascii_link)\n        # Reading SERP\n        read_serp = serp.read()\n        # BeautifulSoup \xe2\x80\x94 https://stackoverflow.com/a/11923803/5951529\n        parsed = BeautifulSoup(read_serp, "lxml")\n        # Parsed first link\n        first_link = parsed.findAll(\n            \'div\', {\'class\': re.compile(\'links_main*\')})[0].a[\'href\']\n        # Remove DuckDuckGo specific characters \xe2\x80\x94\n        # https://stackoverflow.com/a/3942100/5951529\n        remove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")\n        # Final link \xe2\x80\x94 https://stackoverflow.com/a/32451970/5951529\n        final_link = (urllib.parse.unquote(remove_duckduckgo_symbols))\n        markdown_link = \'[\' + selection_text + \']\' + \\\n            \'(\' + final_link + \')\'\n        print(markdown_link)\n\n        # Replace selected text to Markdown link\n        self.view.replace(\n            edit, selection_region, markdown_link)\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

6.没有帮助

\n\n

1.使用电脑全局Python环境

\n\n

我不知道我该怎么做。我可以找到的问题示例:

\n\n\n\n

2.使用Sublime Text环境

\n\n

我安装

\n\n\n\n

我将w3lib目录复制C:\\Python36\\Lib\\site-packagesData\\PackagesSublime Text 目录。

\n\n

我在 Sublime Text 3 控制台中运行:

\n\n
>>> window.run_command("kristinita_lucky_link")\n
Run Code Online (Sandbox Code Playgroud)\n\n

我得到堆栈跟踪:

\n\n
Traceback (most recent call last):\n  File "D:\\Sublime Text Build 3126 x64 For Debug\\sublime_plugin.py", line 109, in reload_plugin\n    m = importlib.import_module(modulename)\n  File "./python3.3/importlib/__init__.py", line 90, in import_module\n  File "<frozen importlib._bootstrap>", line 1584, in _gcd_import\n  File "<frozen importlib._bootstrap>", line 1565, in _find_and_load\n  File "<frozen importlib._bootstrap>", line 1532, in _find_and_load_unlocked\n  File "<frozen importlib._bootstrap>", line 584, in _check_name_wrapper\n  File "<frozen importlib._bootstrap>", line 1022, in load_module\n  File "<frozen importlib._bootstrap>", line 1003, in load_module\n  File "<frozen importlib._bootstrap>", line 560, in module_for_loader_wrapper\n  File "<frozen importlib._bootstrap>", line 868, in _load_module\n  File "<frozen importlib._bootstrap>", line 313, in _call_with_frames_removed\n  File "D:\\Sublime Text Build 3126 x64 For Debug\\Data\\Packages\\Grace Splitter\\kristi.py", line 4, in <module>\n    from bs4 import BeautifulSoup\nImportError: No module named \'bs4\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

我找不到,如何设置lxml

\n\n

3. 在2个文件中使用变量

\n\n

例如,我有KristinitaLuckyLink.pyKrisDuckDuckGo.py文件位于同一目录中。

\n\n

我的KristinitaLuckyLink.py文件:

\n\n
>>> window.run_command("kristinita_lucky_link")\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的KrisDuckDuckGo.py文件:

\n\n
Traceback (most recent call last):\n  File "D:\\Sublime Text 3 x64\\sublime_plugin.py", line 818, in run_\n    return self.run(edit)\n  File "D:\\Sublime Text 3 x64\\Data\\Packages\\KristinitaLuckyLink\\KristinitaLuckyLink.py", line 32, in run\n    parsed = BeautifulSoup(read_serp, "lxml")\n  File "D:\\Sublime Text 3 x64\\Data\\Packages\\bs4\\__init__.py", line 165, in __init__\n    % ",".join(features))\nbs4.FeatureNotFound: Couldn\'t find a tree builder with the features you requested: lxml. Do you need to install a parser library?\n
Run Code Online (Sandbox Code Playgroud)\n\n

我选择在 Sublime Text 控制台中打印的任何文本 \xe2\x86\x92 :

\n\n
\n

window.run_command(“kristinita_lucky_link”)

\n
\n\n

我在 Sublime Text 控制台中没有得到输出。

\n\n
\n\n

7. 环境

\n\n

操作系统和版本:
\nWindows 10 Enterprise LTSB 64 位 EN
\n Sublime Text:
\nBuild 3126
\n Python:
\n3.6.0

\n

Саш*_*ных 2

是的,插件可以与用户全局安装的 Python 模块一起使用。您没有义务向 Sublime Text 插件引入模块。

\n\n

问题

\n\n

1.Python 3.3兼容性

\n\n

为了

\n\n

\xe2\x80\x85\xe2\x80\x85\xe2\x80\x85\xe2\x80\x85您在插件中使用的所有全局模块必须与 Python 3.3 兼容。

\n\n

1.1. 论证

\n\n

1.1.1. Sublime Text sys.path 顺序

\n\n

例如,我添加到Default.sublime-package存档文件0000.py. 首先加载Default.sublime-package来自的模块

\n\n

0000.py内容:

\n\n
import sys\n\nsys.path.append(\'C:\\\\Python36\')\nsys.path.append(\'C:\\\\Python36\\\\python36.zip\')\nsys.path.append(\'C:\\\\Python36\\\\DLLs\')\nsys.path.append(\'C:\\\\Python36\\\\lib\')\nsys.path.append(\'C:\\\\Python36\\\\lib\\\\site-packages\')\n
Run Code Online (Sandbox Code Playgroud)\n\n

其中路径 \xe2\x80\x94 我的全局sys.path.

\n\n
>>> import sys; sys.path\n[\'\', \'C:\\\\Python36\', \'C:\\\\Python36\\\\python36.zip\', \'C:\\\\Python36\\\\DLLs\', \'C:\\\\Python36\\\\lib\', \'C:\\\\Python36\\\\lib\\\\site-packages\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

我重新启动 Sublime Text \xe2\x86\x92 我在控制台中看到:

\n\n
DPI scale: 1\nstartup, version: 3143 windows x64 channel: stable\nexecutable: /D/Sublime Text Build 3143 x64 For Debug/sublime_text.exe\nworking dir: /D/Kristinita\npackages path: /D/Sublime Text Build 3143 x64 For Debug/Data/Packages\nstate path: /D/Sublime Text Build 3143 x64 For Debug/Data/Local\nzip path: /D/Sublime Text Build 3143 x64 For Debug/Packages\nzip path: /D/Sublime Text Build 3143 x64 For Debug/Data/Installed Packages\nignored_packages: ["Anaconda", "Vintage"]\npre session restore time: 0.458819\nstartup time: 0.493818\nfirst paint time: 0.506818\nreloading plugin Default.0000\nreloading plugin Default.auto_indent_tag\nreloading plugin Default.block\n# And so on\n
Run Code Online (Sandbox Code Playgroud)\n\n
>>> import sys; sys.path\n[\'D:\\\\Sublime Text Build 3143 x64 For Debug\', \'D:\\\\Sublime Text Build 3143 x64 For Debug\\\\python3.3.zip\', \'D:\\\\Sublime Text Build 3143 x64 For Debug\\\\Data\\\\Lib\\\\python3.3\', \'D:\\\\Sublime Text Build 3143 x64 For Debug\\\\Data\\\\Packages\', \'C:\\\\Python36\', \'C:\\\\Python36\\\\python36.zip\', \'C:\\\\Python36\\\\DLLs\', \'C:\\\\Python36\\\\lib\', \'C:\\\\Python36\\\\lib\\\\site-packages\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

来自内部环境的路径在前面,即全局环境中的路径。我不知道,我该如何改变它。

\n\n

1.1.2. Python 3.6 模块

\n\n

例如,我想在我的插件中使用Python Google Search API PyPI 模块。它兼容Python 3.6,但不兼容Python 3.3

\n\n

0000.py按照上面的小节注入文件 \xe2\x86\x92 我创建插件SashaGSearch.py,其内容:

\n\n
import sublime_plugin\n\nfrom gsearch.googlesearch import search\n\n\nclass GoogleSearchCommand(sublime_plugin.TextCommand):\n\n    def run(self, edit):\n\n        results = search(\'kristinitaluckylife\', num_results=1)\n        r = results[0][1]\n        print(r)\n
Run Code Online (Sandbox Code Playgroud)\n\n

我重新启动 Sublime Text \xe2\x86\x92 我得到相同的回溯,就好像0000.py没有实现一样。

\n\n

1.2. 2018年年初情况

\n\n

请参阅 Sublime Text 论坛讨论:

\n\n\n\n

我希望,在内部 Sublime Text 环境中,Python 3.3 将在不久的将来替换为 3.6 或下一个 3.7 版本。

\n\n
\n\n

2.环境变量

\n\n

如果您知道,可能不要添加新的环境变量,请回答这个问题

\n\n

2.1. 插件代码

\n\n

您需要在 PC 上创建环境变量,其中值为 \xe2\x80\x94site-packages文件夹路径。例如,我将其命名为PYTHONPACKAGES

\n\n

您需要添加到代码行中,如OdatNurd 答案

\n\n
# PYTHONPACKAGES path:\n# https://stackoverflow.com/a/4907053/5951529\n# Disable duplicate paths:\n# https://stackoverflow.com/a/42656754/5951529\nsite_packages = (os.environ[\'PYTHONPACKAGES\'])\nif site_packages not in sys.path:\n    sys.path.append(site_packages)\n
Run Code Online (Sandbox Code Playgroud)\n\n

2.2. 激活说明

\n\n

您的插件的用户还必须添加环境变量PYTHONPACKAGES在操作系统中添加环境变量。在你的包裹的描述中,你需要添加说明,如何做。

\n\n\n\n
\n\n

3. 重新启动

\n\n

对于开发过程:

\n\n

\xe2\x80\x85\xe2\x80\x85\xe2\x80\x85\xe2\x80\x85如果更改文件夹或子文件夹中的文件,您可能需要重新启动 Sublime Text site-packages

\n\n

3.1. 例子

\n\n

您从 pip 安装examplesashamodule\xe2\x86\x92 您启动 Sublime Text \xe2\x86\x92 您导入examplesashamodule到您的插件 \xe2\x86\x92 您examplesashamodulesite-packages文件夹中删除 \xe2\x86\x92 插件将像examplesashamodule仍在site-packages文件夹中一样工作。在这种情况下, AutomaticPackageReloader包没有帮助。

\n\n

重新启动 Sublime Text \xe2\x86\x92 后,您会在 Sublime Text 控制台中得到回溯,即ImportError: No module named \'examplesashamodule\'.

\n\n

显然,Sublime Text 在会话中缓存来自外部模块的数据。

\n