Sublime Text 插件开发中的全局 Python 个包
Global Python packages in Sublime Text plugin development
1。摘要
我没找到,Sublime Text 插件开发者如何使用 Sublime Text 找到全局 Python 包,而不是 Sublime Text 目录的 Python 包。
Sublime Text 使用自己的 Python 环境,而不是机器的 Python 环境。 Developers needs sys.path
用于设置非内置 Sublime Text Python 包。
是否有任何方法在 Sublime Text 插件中使用全局安装的 Python 包?例如,如果有人告诉我如何更改我的插件,那就太好了——请参阅本问题的 3.2 项。
2。使用 Sublime Text 3 环境的缺点
- Sublime Text 3 Build 3126 使用 Python 3.3,但在撰写此问题时发布 Python 3.6 稳定版。 Python 3.6 有更多功能。
- 开发人员需要添加和更新第三方 Python 包,即使他们为用户安装。它花费了开发人员的时间。
- 开发者可能会遇到包依赖问题,见本题第6.2条。
3。范例
1。 Python代码
例如,我写了Python代码——将Поиск Кристиниты
替换为[**Поиск Кристиниты**](https://github.com/Kristinita/Kristinita.github.io)
,其中https://github.com/Kristinita/Kristinita.github.io
——DuckDuckGo查询的第一个linkПоиск Кристиниты
.
# -*- coding: utf-8 -*-
import re
import urllib
from bs4 import BeautifulSoup
from w3lib.url import safe_url_string
# ASCII link for solved encoding problems —
#
ascii_link = safe_url_string(
u'http://duckduckgo.com/html/?q=' + 'Поиск Кристиниты',
encoding="UTF-8")
print(ascii_link)
# SERP DuckDuckGo
serp = urllib.request.urlopen(ascii_link)
# Reading SERP
read_serp = serp.read()
# BeautifulSoup —
parsed = BeautifulSoup(read_serp, "lxml")
# Parsed first link
first_link = parsed.findAll(
'div', {'class': re.compile('links_main*')})[0].a['href']
# Remove DuckDuckGo specific characters —
#
remove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")
#
final_link = (urllib.parse.unquote(remove_duckduckgo_symbols))
# Markdown link
markdown_link = '[' + 'Поиск Кристиниты' + ']' + \
'(' + final_link + ')'
print(markdown_link)
如果我在终端或 SublimeREPL 中 运行 这个文件,我得到输出:
[**Поиск Кристиниты**](https://github.com/Kristinita/Kristinita.github.io/)
2。 Sublime Text 插件
现在,基于这段代码,我编写了用于将 example text
替换为 [**example text**](http://<first link for DuckDuckGo query “example link”>)
:
的 Sublime Text 插件
import re
import urllib
from bs4 import BeautifulSoup
from w3lib.url import safe_url_string
import sublime_plugin
class KristinitaLuckyLinkCommand(sublime_plugin.TextCommand):
def run(self, edit):
# Get selection text
print('KristinitaLuckyLink called')
select = self.view.sel()
selection_region = select[0]
selection_text = self.view.substr(selection_region)
print(selection_text)
# ASCII link for solved encoding problems —
#
ascii_link = safe_url_string(
u'http://duckduckgo.com/html/?q=' + (selection_text),
encoding="UTF-8")
print(ascii_link)
# SERP DuckDuckGo
serp = urllib.request.urlopen(ascii_link)
# Reading SERP
read_serp = serp.read()
# BeautifulSoup —
parsed = BeautifulSoup(read_serp, "lxml")
# Parsed first link
first_link = parsed.findAll(
'div', {'class': re.compile('links_main*')})[0].a['href']
# Remove DuckDuckGo specific characters —
#
remove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")
# Final link —
final_link = (urllib.parse.unquote(remove_duckduckgo_symbols))
markdown_link = '[' + selection_text + ']' + \
'(' + final_link + ')'
print(markdown_link)
# Replace selected text to Markdown link
self.view.replace(
edit, selection_region, markdown_link)
4。预期行为
如果用户已安装 Python 并安装软件包
pip install beautifulsoup4
pip install lxml
pip install w3lib
我希望我的 2.2 项插件能够成功地为用户工作。
5。实际行为
如果我保存我的插件,我得到堆栈跟踪:
Traceback (most recent call last):
File "D:\Sublime Text Build 3126 x64 For Debug\sublime_plugin.py", line 109, in reload_plugin
m = importlib.import_module(modulename)
File "./python3.3/importlib/__init__.py", line 90, in import_module
File "<frozen importlib._bootstrap>", line 1584, in _gcd_import
File "<frozen importlib._bootstrap>", line 1565, in _find_and_load
File "<frozen importlib._bootstrap>", line 1532, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 584, in _check_name_wrapper
File "<frozen importlib._bootstrap>", line 1022, in load_module
File "<frozen importlib._bootstrap>", line 1003, in load_module
File "<frozen importlib._bootstrap>", line 560, in module_for_loader_wrapper
File "<frozen importlib._bootstrap>", line 868, in _load_module
File "<frozen importlib._bootstrap>", line 313, in _call_with_frames_removed
File "D:\Sublime Text Build 3126 x64 For Debug\Data\Packages\Grace Splitter\kristi.py", line 4, in <module>
from bs4 import BeautifulSoup
ImportError: No module named 'bs4'
6。没有帮助
1。使用计算机
的全局Python环境
我没有找到我该怎么做。我可以找到的问题示例:
- How to include third party Python packages in Sublime Text 2 plugins,
- Using paramiko library in ST2 plugins,
- Best practices for plugin-deployment and packaging,
- How to import a package and call its global functions / to get their global variable values?
2。使用 Sublime Text 环境
我安装
我将 w3lib
目录从 C:\Python36\Lib\site-packages
复制到 Sublime Text 的 Data\Packages
目录。
我在 Sublime Text 3 控制台中 运行:
>>> window.run_command("kristinita_lucky_link")
我得到堆栈跟踪:
Traceback (most recent call last):
File "D:\Sublime Text 3 x64\sublime_plugin.py", line 818, in run_
return self.run(edit)
File "D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\KristinitaLuckyLink.py", line 32, in run
parsed = BeautifulSoup(read_serp, "lxml")
File "D:\Sublime Text 3 x64\Data\Packages\bs4\__init__.py", line 165, in __init__
% ",".join(features))
bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
没找到,怎么设置lxml
.
3。在 2 个文件中使用变量
例如,我在同一目录中有 KristinitaLuckyLink.py
和 KrisDuckDuckGo.py
个文件。
我的KristinitaLuckyLink.py
文件:
import re
import requests
import sublime_plugin
import subprocess
import sys
sys.path.append(
'D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\KrisDuckDuckGo.py')
from KrisDuckDuckGo import final_link
from bs4 import BeautifulSoup
class KristinitaLuckyLinkCommand(sublime_plugin.TextCommand):
def run(self, edit):
# Get selection text
print('KristinitaLuckyLink called')
select = self.view.sel()
selection_region = select[0]
selection_text = self.view.substr(selection_region)
print(selection_text)
# Get terminal output —
# Paths is correct
result = subprocess.run(["C:\Python36\python.exe", "D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\krisduckduckgo.py"],
stdout=subprocess.PIPE)
final_link = result.stdout.decode('utf-8')
print(final_link)
# Markdown link
markdown_link = '[' + selection_text + ']' + \
'(' + final_link + ')'
print(markdown_link)
# Replace selected text to Markdown link
self.view.replace(
edit, selection_region, markdown_link)
我的KrisDuckDuckGo.py
文件:
import urllib
import sys
sys.path.append(
'D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\KristinitaLuckyLink.py')
from w3lib.url import safe_url_string
from KristinitaLuckyLink import selection_text
from bs4 import BeautifulSoup
# ASCII link for solved encoding problems —
#
ascii_link = safe_url_string(
u'http://duckduckgo.com/html/?q=' + (selection_text),
encoding="UTF-8")
print(ascii_link)
# SERP DuckDuckGo
serp = urllib.request.urlopen(ascii_link)
# Reading SERP
read_serp = serp.read()
# BeautifulSoup —
parsed = BeautifulSoup(read_serp, "lxml")
# Parsed first link
first_link = parsed.findAll(
'div', {'class': re.compile('links_main*')})[0].a['href']
# Remove DuckDuckGo specific characters —
#
remove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")
# Final link —
final_link = (urllib.parse.unquote(remove_duckduckgo_symbols))
print(final_link)
我 select 任何文本 → 我在 Sublime Text 控制台打印:
window.run_command("kristinita_lucky_link")
我在 Sublime Text 控制台中没有得到输出。
7。环境
操作系统及版本:
Windows 10 企业 LTSB 64 位 EN
Sublime 文本:
建造 3126
Python:
3.6.0
Python 通过 sys.path
从它知道的位置加载模块,而在 Sublime Text 3 中 sys.path
仅指向几个位置(例如随附的包的位置Sublime 可执行文件、当前用户安装包的位置等)。
为了从 Sublime 文本插件中访问全局安装的 Python 模块,您需要从插件中明确地将其位置添加到 sys.path
。
假设 Linux 机器的 python 软件包安装在 /usr/local/lib/python3.4/site-packages
中(将其修改为适合您的 Windows 机器的任何路径),例如这将如下所示:
import sublime
import sublime_plugin
import sys
site_path="/usr/local/lib/python3.4/site-packages"
if site_path not in sys.path:
sys.path.append(site_path)
from bs4 import BeautifulSoup
class ExampleCommand(sublime_plugin.TextCommand):
def run(self, edit):
parser = BeautifulSoup('<a href="#">Link Text</a>', "html.parser")
a = parser.find("a")
text = a.contents[0]
self.view.insert(edit, 0, text)
如果sys.path
还没有路径,这会专门添加路径,以便导入和使用模块。
Sublime 包含它自己独特的 Python 版本,专门针对沙箱本身,因此它完全不依赖任何版本的 python 或任何安装在 python 上的包用于 运行 它的计算机,这就是默认情况下它不为您执行此操作的原因。
如果你想在你的计算机上使用 Python 版本,Sublime 没有提供,你可以使用以下 Sublime 命令:
window.run_command("exec", {"shell_cmd" : '<your command here>'})
此命令允许您在 Sublime 之外的计算机上执行应用程序。
只需将 <your command here>
替换为您要执行的 shell 命令即可。
输出将在崇高的输出面板(终端)中返回。该输出面板与 Sublime 控制台不同。
您可以将要使用的本地 Python 的路径放在那里,并使用脚本(需要额外的 Python 模块)作为参数。
例如:
window.run_command("exec", {"shell_cmd" : 'C:\Python36\python.exe D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\LuckyLink\LuckyLink.py'})
不过您需要将您的包拆分成两个文件。一个描述你的包和 Sublime 内部所需命令的文件。另一个文件(它应该在你的包目录的子目录中——这样它就不会被 Sublime 视为插件)包含你的代码的其余部分。
第二个文件是导入 Sublime 内部 Python 中未包含的 Python 模块的地方。
此外,您需要找到一种方法将您要使用的选择或 string/url 转移到第二个脚本。
你可以在我的 Sublime 包中查看我是如何做到的 PlotGraph。
错误:
bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
最有可能是因为 Sublime Text 发现 lxml
作为全局 Python 环境的一部分安装 - 它是为不同版本的 Python 编译的,而不是 ST使用 - 所以它无法加载它。
我们想要的是让 ST 找到您在问题中链接到的 sublime-lxml
依赖项。 "Why is it finding the wrong one?",你可能会问。很难确定,但我认为 - ST 出于某种原因看到的 sys.path
包括所有全局 Python 包。默认情况下,ST 应仅使用其可执行文件所在的文件夹和 ST 数据目录中的 Packages 文件夹。例如,在我的系统上,在 ST 的控制台中执行 import sys; sys.path
会得到:
[
'C:\Program Files\Sublime Text 3',
'C:\Program Files\Sublime Text 3/python3.3.zip',
'C:\Users\Keith\AppData\Roaming\Sublime Text 3\Packages',
'C:\Users\Keith\AppData\Roaming\SUBLIM~1\Packages\lxml\ST3_WI~2'
]
即没有 site-packages
个文件夹。
因此解决方案是:
一个。您可以尝试卸载系统范围的 lxml
包,这样 ST 只会找到 sublime-lxml
依赖包,但实际上这只是一个临时措施。最好是:
b.调整 ST 使用的路径环境变量(项目顺序)。 (即删除所有对 site-packages
的引用,或者至少移动它们,使它们位于 ST 文件夹之后。)
选项 B 应该不会影响任何其他 ST 插件,因为它们也会遇到同样的问题。我怀疑其他一些包改变了 ST 使用的路径,但如果不搜索所有包,可能不容易找出是哪一个包。当使用构建系统时,用于这些的路径与插件用于加载其模块的路径完全不同,因此构建系统也应该不受此影响"fix"。
是的,插件可以与用户在全局安装的 Python 模块一起使用。您没有义务为您的 Sublime Text 插件引入模块。
问题
1。 Python 3.3 兼容性
2018 年初:
您在插件中使用的所有全局模块必须与 Python 3.3.
兼容
1.1。争论
1.1.1。 Sublime Text sys.path 订单
比如我添加到Default.sublime-package
存档文件0000.py
。来自 Default.sublime-package
的模块由 Sublime Text 启动 loaded first。
0000.py
内容:
import sys
sys.path.append('C:\Python36')
sys.path.append('C:\Python36\python36.zip')
sys.path.append('C:\Python36\DLLs')
sys.path.append('C:\Python36\lib')
sys.path.append('C:\Python36\lib\site-packages')
Where路径——我的全局sys.path
.
>>> import sys; sys.path
['', 'C:\Python36', 'C:\Python36\python36.zip', 'C:\Python36\DLLs', 'C:\Python36\lib', 'C:\Python36\lib\site-packages']
我重新启动 Sublime Text → 我在控制台中看到:
DPI scale: 1
startup, version: 3143 windows x64 channel: stable
executable: /D/Sublime Text Build 3143 x64 For Debug/sublime_text.exe
working dir: /D/Kristinita
packages path: /D/Sublime Text Build 3143 x64 For Debug/Data/Packages
state path: /D/Sublime Text Build 3143 x64 For Debug/Data/Local
zip path: /D/Sublime Text Build 3143 x64 For Debug/Packages
zip path: /D/Sublime Text Build 3143 x64 For Debug/Data/Installed Packages
ignored_packages: ["Anaconda", "Vintage"]
pre session restore time: 0.458819
startup time: 0.493818
first paint time: 0.506818
reloading plugin Default.0000
reloading plugin Default.auto_indent_tag
reloading plugin Default.block
# And so on
>>> import sys; sys.path
['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']
内部环境的路径在前,全局环境的路径在前。不知道怎么改。
1.1.2。 Python 3.6 模块
比如我想在我的插件中使用Python Google Search API PyPI module. It compatible with Python 3.6, but not compatible with Python 3.3.
我按照上面的小节注入文件 0000.py
→ 我创建插件 SashaGSearch.py
,它的内容:
import sublime_plugin
from gsearch.googlesearch import search
class GoogleSearchCommand(sublime_plugin.TextCommand):
def run(self, edit):
results = search('kristinitaluckylife', num_results=1)
r = results[0][1]
print(r)
我重启Sublime Text → 我得到same traceback,好像0000.py
没有执行。
1.2。 2018年初情况
查看 Sublime Text 论坛讨论:
我希望,在内部 Sublime Text 环境中 Python 3.3 将在不久的将来被替换为 3.6 或下一个 3.7 版本。
2。环境变量
如果你知道,那可能不添加新的环境变量,请回答this question。
2.1。插件代码
您需要在您的 PC 上创建环境变量,其中值 — site-packages
文件夹的路径。比如我命名为PYTHONPACKAGES
:
您需要添加到代码行中,如 :
# PYTHONPACKAGES path:
#
# Disable duplicate paths:
#
site_packages = (os.environ['PYTHONPACKAGES'])
if site_packages not in sys.path:
sys.path.append(site_packages)
2.2。激活说明
使用您的插件的用户还必须在操作系统中添加环境变量PYTHONPACKAGES
。在您的包裹描述中,您需要添加说明,如何做。
3。重启
对于开发过程:
如果您更改 site-packages
文件夹或子文件夹中的文件,您可能需要重新启动 Sublime Text。
3.1。范例
你从 pip 安装 examplesashamodule
→ 你启动 Sublime Text → 你导入 examplesashamodule
到你的插件 → 你从 site-packages
文件夹中删除 examplesashamodule
→ 插件将作为examplesashamodule
仍在 site-packages
文件夹中。 AutomaticPackageReloader 包在这种情况下没有帮助。
你重新启动 Sublime Text → 你在 Sublime Text 控制台中得到回溯,ImportError: No module named 'examplesashamodule'
。
显然,Sublime Text 在会话中缓存来自外部模块的数据。
1。摘要
我没找到,Sublime Text 插件开发者如何使用 Sublime Text 找到全局 Python 包,而不是 Sublime Text 目录的 Python 包。
Sublime Text 使用自己的 Python 环境,而不是机器的 Python 环境。 Developers needs sys.path
用于设置非内置 Sublime Text Python 包。
是否有任何方法在 Sublime Text 插件中使用全局安装的 Python 包?例如,如果有人告诉我如何更改我的插件,那就太好了——请参阅本问题的 3.2 项。
2。使用 Sublime Text 3 环境的缺点
- Sublime Text 3 Build 3126 使用 Python 3.3,但在撰写此问题时发布 Python 3.6 稳定版。 Python 3.6 有更多功能。
- 开发人员需要添加和更新第三方 Python 包,即使他们为用户安装。它花费了开发人员的时间。
- 开发者可能会遇到包依赖问题,见本题第6.2条。
3。范例
1。 Python代码
例如,我写了Python代码——将Поиск Кристиниты
替换为[**Поиск Кристиниты**](https://github.com/Kristinita/Kristinita.github.io)
,其中https://github.com/Kristinita/Kristinita.github.io
——DuckDuckGo查询的第一个linkПоиск Кристиниты
.
# -*- coding: utf-8 -*-
import re
import urllib
from bs4 import BeautifulSoup
from w3lib.url import safe_url_string
# ASCII link for solved encoding problems —
#
ascii_link = safe_url_string(
u'http://duckduckgo.com/html/?q=' + 'Поиск Кристиниты',
encoding="UTF-8")
print(ascii_link)
# SERP DuckDuckGo
serp = urllib.request.urlopen(ascii_link)
# Reading SERP
read_serp = serp.read()
# BeautifulSoup —
parsed = BeautifulSoup(read_serp, "lxml")
# Parsed first link
first_link = parsed.findAll(
'div', {'class': re.compile('links_main*')})[0].a['href']
# Remove DuckDuckGo specific characters —
#
remove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")
#
final_link = (urllib.parse.unquote(remove_duckduckgo_symbols))
# Markdown link
markdown_link = '[' + 'Поиск Кристиниты' + ']' + \
'(' + final_link + ')'
print(markdown_link)
如果我在终端或 SublimeREPL 中 运行 这个文件,我得到输出:
[**Поиск Кристиниты**](https://github.com/Kristinita/Kristinita.github.io/)
2。 Sublime Text 插件
现在,基于这段代码,我编写了用于将 example text
替换为 [**example text**](http://<first link for DuckDuckGo query “example link”>)
:
import re
import urllib
from bs4 import BeautifulSoup
from w3lib.url import safe_url_string
import sublime_plugin
class KristinitaLuckyLinkCommand(sublime_plugin.TextCommand):
def run(self, edit):
# Get selection text
print('KristinitaLuckyLink called')
select = self.view.sel()
selection_region = select[0]
selection_text = self.view.substr(selection_region)
print(selection_text)
# ASCII link for solved encoding problems —
#
ascii_link = safe_url_string(
u'http://duckduckgo.com/html/?q=' + (selection_text),
encoding="UTF-8")
print(ascii_link)
# SERP DuckDuckGo
serp = urllib.request.urlopen(ascii_link)
# Reading SERP
read_serp = serp.read()
# BeautifulSoup —
parsed = BeautifulSoup(read_serp, "lxml")
# Parsed first link
first_link = parsed.findAll(
'div', {'class': re.compile('links_main*')})[0].a['href']
# Remove DuckDuckGo specific characters —
#
remove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")
# Final link —
final_link = (urllib.parse.unquote(remove_duckduckgo_symbols))
markdown_link = '[' + selection_text + ']' + \
'(' + final_link + ')'
print(markdown_link)
# Replace selected text to Markdown link
self.view.replace(
edit, selection_region, markdown_link)
4。预期行为
如果用户已安装 Python 并安装软件包
pip install beautifulsoup4
pip install lxml
pip install w3lib
我希望我的 2.2 项插件能够成功地为用户工作。
5。实际行为
如果我保存我的插件,我得到堆栈跟踪:
Traceback (most recent call last):
File "D:\Sublime Text Build 3126 x64 For Debug\sublime_plugin.py", line 109, in reload_plugin
m = importlib.import_module(modulename)
File "./python3.3/importlib/__init__.py", line 90, in import_module
File "<frozen importlib._bootstrap>", line 1584, in _gcd_import
File "<frozen importlib._bootstrap>", line 1565, in _find_and_load
File "<frozen importlib._bootstrap>", line 1532, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 584, in _check_name_wrapper
File "<frozen importlib._bootstrap>", line 1022, in load_module
File "<frozen importlib._bootstrap>", line 1003, in load_module
File "<frozen importlib._bootstrap>", line 560, in module_for_loader_wrapper
File "<frozen importlib._bootstrap>", line 868, in _load_module
File "<frozen importlib._bootstrap>", line 313, in _call_with_frames_removed
File "D:\Sublime Text Build 3126 x64 For Debug\Data\Packages\Grace Splitter\kristi.py", line 4, in <module>
from bs4 import BeautifulSoup
ImportError: No module named 'bs4'
6。没有帮助
1。使用计算机
的全局Python环境我没有找到我该怎么做。我可以找到的问题示例:
- How to include third party Python packages in Sublime Text 2 plugins,
- Using paramiko library in ST2 plugins,
- Best practices for plugin-deployment and packaging,
- How to import a package and call its global functions / to get their global variable values?
2。使用 Sublime Text 环境
我安装
我将 w3lib
目录从 C:\Python36\Lib\site-packages
复制到 Sublime Text 的 Data\Packages
目录。
我在 Sublime Text 3 控制台中 运行:
>>> window.run_command("kristinita_lucky_link")
我得到堆栈跟踪:
Traceback (most recent call last):
File "D:\Sublime Text 3 x64\sublime_plugin.py", line 818, in run_
return self.run(edit)
File "D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\KristinitaLuckyLink.py", line 32, in run
parsed = BeautifulSoup(read_serp, "lxml")
File "D:\Sublime Text 3 x64\Data\Packages\bs4\__init__.py", line 165, in __init__
% ",".join(features))
bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
没找到,怎么设置lxml
.
3。在 2 个文件中使用变量
例如,我在同一目录中有 KristinitaLuckyLink.py
和 KrisDuckDuckGo.py
个文件。
我的KristinitaLuckyLink.py
文件:
import re
import requests
import sublime_plugin
import subprocess
import sys
sys.path.append(
'D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\KrisDuckDuckGo.py')
from KrisDuckDuckGo import final_link
from bs4 import BeautifulSoup
class KristinitaLuckyLinkCommand(sublime_plugin.TextCommand):
def run(self, edit):
# Get selection text
print('KristinitaLuckyLink called')
select = self.view.sel()
selection_region = select[0]
selection_text = self.view.substr(selection_region)
print(selection_text)
# Get terminal output —
# Paths is correct
result = subprocess.run(["C:\Python36\python.exe", "D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\krisduckduckgo.py"],
stdout=subprocess.PIPE)
final_link = result.stdout.decode('utf-8')
print(final_link)
# Markdown link
markdown_link = '[' + selection_text + ']' + \
'(' + final_link + ')'
print(markdown_link)
# Replace selected text to Markdown link
self.view.replace(
edit, selection_region, markdown_link)
我的KrisDuckDuckGo.py
文件:
import urllib
import sys
sys.path.append(
'D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\KristinitaLuckyLink.py')
from w3lib.url import safe_url_string
from KristinitaLuckyLink import selection_text
from bs4 import BeautifulSoup
# ASCII link for solved encoding problems —
#
ascii_link = safe_url_string(
u'http://duckduckgo.com/html/?q=' + (selection_text),
encoding="UTF-8")
print(ascii_link)
# SERP DuckDuckGo
serp = urllib.request.urlopen(ascii_link)
# Reading SERP
read_serp = serp.read()
# BeautifulSoup —
parsed = BeautifulSoup(read_serp, "lxml")
# Parsed first link
first_link = parsed.findAll(
'div', {'class': re.compile('links_main*')})[0].a['href']
# Remove DuckDuckGo specific characters —
#
remove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")
# Final link —
final_link = (urllib.parse.unquote(remove_duckduckgo_symbols))
print(final_link)
我 select 任何文本 → 我在 Sublime Text 控制台打印:
window.run_command("kristinita_lucky_link")
我在 Sublime Text 控制台中没有得到输出。
7。环境
操作系统及版本:
Windows 10 企业 LTSB 64 位 EN
Sublime 文本:
建造 3126
Python:
3.6.0
Python 通过 sys.path
从它知道的位置加载模块,而在 Sublime Text 3 中 sys.path
仅指向几个位置(例如随附的包的位置Sublime 可执行文件、当前用户安装包的位置等)。
为了从 Sublime 文本插件中访问全局安装的 Python 模块,您需要从插件中明确地将其位置添加到 sys.path
。
假设 Linux 机器的 python 软件包安装在 /usr/local/lib/python3.4/site-packages
中(将其修改为适合您的 Windows 机器的任何路径),例如这将如下所示:
import sublime
import sublime_plugin
import sys
site_path="/usr/local/lib/python3.4/site-packages"
if site_path not in sys.path:
sys.path.append(site_path)
from bs4 import BeautifulSoup
class ExampleCommand(sublime_plugin.TextCommand):
def run(self, edit):
parser = BeautifulSoup('<a href="#">Link Text</a>', "html.parser")
a = parser.find("a")
text = a.contents[0]
self.view.insert(edit, 0, text)
如果sys.path
还没有路径,这会专门添加路径,以便导入和使用模块。
Sublime 包含它自己独特的 Python 版本,专门针对沙箱本身,因此它完全不依赖任何版本的 python 或任何安装在 python 上的包用于 运行 它的计算机,这就是默认情况下它不为您执行此操作的原因。
如果你想在你的计算机上使用 Python 版本,Sublime 没有提供,你可以使用以下 Sublime 命令:
window.run_command("exec", {"shell_cmd" : '<your command here>'})
此命令允许您在 Sublime 之外的计算机上执行应用程序。
只需将 <your command here>
替换为您要执行的 shell 命令即可。
输出将在崇高的输出面板(终端)中返回。该输出面板与 Sublime 控制台不同。
您可以将要使用的本地 Python 的路径放在那里,并使用脚本(需要额外的 Python 模块)作为参数。 例如:
window.run_command("exec", {"shell_cmd" : 'C:\Python36\python.exe D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\LuckyLink\LuckyLink.py'})
不过您需要将您的包拆分成两个文件。一个描述你的包和 Sublime 内部所需命令的文件。另一个文件(它应该在你的包目录的子目录中——这样它就不会被 Sublime 视为插件)包含你的代码的其余部分。 第二个文件是导入 Sublime 内部 Python 中未包含的 Python 模块的地方。 此外,您需要找到一种方法将您要使用的选择或 string/url 转移到第二个脚本。
你可以在我的 Sublime 包中查看我是如何做到的 PlotGraph。
错误:
bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
最有可能是因为 Sublime Text 发现 lxml
作为全局 Python 环境的一部分安装 - 它是为不同版本的 Python 编译的,而不是 ST使用 - 所以它无法加载它。
我们想要的是让 ST 找到您在问题中链接到的 sublime-lxml
依赖项。 "Why is it finding the wrong one?",你可能会问。很难确定,但我认为 sys.path
包括所有全局 Python 包。默认情况下,ST 应仅使用其可执行文件所在的文件夹和 ST 数据目录中的 Packages 文件夹。例如,在我的系统上,在 ST 的控制台中执行 import sys; sys.path
会得到:
[
'C:\Program Files\Sublime Text 3',
'C:\Program Files\Sublime Text 3/python3.3.zip',
'C:\Users\Keith\AppData\Roaming\Sublime Text 3\Packages',
'C:\Users\Keith\AppData\Roaming\SUBLIM~1\Packages\lxml\ST3_WI~2'
]
即没有 site-packages
个文件夹。
因此解决方案是:
一个。您可以尝试卸载系统范围的 lxml
包,这样 ST 只会找到 sublime-lxml
依赖包,但实际上这只是一个临时措施。最好是:
b.调整 ST 使用的路径环境变量(项目顺序)。 (即删除所有对 site-packages
的引用,或者至少移动它们,使它们位于 ST 文件夹之后。)
选项 B 应该不会影响任何其他 ST 插件,因为它们也会遇到同样的问题。我怀疑其他一些包改变了 ST 使用的路径,但如果不搜索所有包,可能不容易找出是哪一个包。当使用构建系统时,用于这些的路径与插件用于加载其模块的路径完全不同,因此构建系统也应该不受此影响"fix"。
是的,插件可以与用户在全局安装的 Python 模块一起使用。您没有义务为您的 Sublime Text 插件引入模块。
问题
1。 Python 3.3 兼容性
2018 年初:
您在插件中使用的所有全局模块必须与 Python 3.3.
兼容1.1。争论
1.1.1。 Sublime Text sys.path 订单
比如我添加到Default.sublime-package
存档文件0000.py
。来自 Default.sublime-package
的模块由 Sublime Text 启动 loaded first。
0000.py
内容:
import sys
sys.path.append('C:\Python36')
sys.path.append('C:\Python36\python36.zip')
sys.path.append('C:\Python36\DLLs')
sys.path.append('C:\Python36\lib')
sys.path.append('C:\Python36\lib\site-packages')
Where路径——我的全局sys.path
.
>>> import sys; sys.path
['', 'C:\Python36', 'C:\Python36\python36.zip', 'C:\Python36\DLLs', 'C:\Python36\lib', 'C:\Python36\lib\site-packages']
我重新启动 Sublime Text → 我在控制台中看到:
DPI scale: 1
startup, version: 3143 windows x64 channel: stable
executable: /D/Sublime Text Build 3143 x64 For Debug/sublime_text.exe
working dir: /D/Kristinita
packages path: /D/Sublime Text Build 3143 x64 For Debug/Data/Packages
state path: /D/Sublime Text Build 3143 x64 For Debug/Data/Local
zip path: /D/Sublime Text Build 3143 x64 For Debug/Packages
zip path: /D/Sublime Text Build 3143 x64 For Debug/Data/Installed Packages
ignored_packages: ["Anaconda", "Vintage"]
pre session restore time: 0.458819
startup time: 0.493818
first paint time: 0.506818
reloading plugin Default.0000
reloading plugin Default.auto_indent_tag
reloading plugin Default.block
# And so on
>>> import sys; sys.path
['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']
内部环境的路径在前,全局环境的路径在前。不知道怎么改。
1.1.2。 Python 3.6 模块
比如我想在我的插件中使用Python Google Search API PyPI module. It compatible with Python 3.6, but not compatible with Python 3.3.
我按照上面的小节注入文件 0000.py
→ 我创建插件 SashaGSearch.py
,它的内容:
import sublime_plugin
from gsearch.googlesearch import search
class GoogleSearchCommand(sublime_plugin.TextCommand):
def run(self, edit):
results = search('kristinitaluckylife', num_results=1)
r = results[0][1]
print(r)
我重启Sublime Text → 我得到same traceback,好像0000.py
没有执行。
1.2。 2018年初情况
查看 Sublime Text 论坛讨论:
我希望,在内部 Sublime Text 环境中 Python 3.3 将在不久的将来被替换为 3.6 或下一个 3.7 版本。
2。环境变量
如果你知道,那可能不添加新的环境变量,请回答this question。
2.1。插件代码
您需要在您的 PC 上创建环境变量,其中值 — site-packages
文件夹的路径。比如我命名为PYTHONPACKAGES
:
您需要添加到代码行中,如
# PYTHONPACKAGES path:
#
# Disable duplicate paths:
#
site_packages = (os.environ['PYTHONPACKAGES'])
if site_packages not in sys.path:
sys.path.append(site_packages)
2.2。激活说明
使用您的插件的用户还必须在操作系统中添加环境变量PYTHONPACKAGES
。在您的包裹描述中,您需要添加说明,如何做。
3。重启
对于开发过程:
如果您更改 site-packages
文件夹或子文件夹中的文件,您可能需要重新启动 Sublime Text。
3.1。范例
你从 pip 安装 examplesashamodule
→ 你启动 Sublime Text → 你导入 examplesashamodule
到你的插件 → 你从 site-packages
文件夹中删除 examplesashamodule
→ 插件将作为examplesashamodule
仍在 site-packages
文件夹中。 AutomaticPackageReloader 包在这种情况下没有帮助。
你重新启动 Sublime Text → 你在 Sublime Text 控制台中得到回溯,ImportError: No module named 'examplesashamodule'
。
显然,Sublime Text 在会话中缓存来自外部模块的数据。