在崇高的文本插件开发全球Python包

问题描述 投票:3回答:4

1.摘要

我不觉得,崇高文本插件开发者如何使用文本崇高找到全球Python包,崇高的文本目录的不Python包。

崇高文本中使用自己的Python环境,机器的不是Python环境。对于集Developers needs sys.path没有内置崇高文本Python包。

在任何方法,使用全球安装Python包的崇高文字插件?例如,这将是很好,如果有人告诉我,我怎样才能改变我的插件 - 看到这个问题的3.2项。


2.使用崇高文本3环境的缺点

  1. 崇高的文本3建筑3126使用Python 3.3,但在写这个问题的时候发布的Python 3.6的稳定。 Python的3.6有更多的功能。
  2. 开发者需要添加和更新第三方Python包,即使他们安装的用户。它花费的开发时间。
  3. 对于开发者有可能是包的依赖问题,看到这个问题的6.2项。

3.实施例

1. Python code

例如,我写的Python代码 - 取代Поиск Кристиниты[**Поиск Кристиниты**](https://github.com/Kristinita/Kristinita.github.io),其中https://github.com/Kristinita/Kristinita.github.io - DuckDuckGo查询Поиск Кристиниты的首要环节。

# -*- coding: utf-8 -*-
import re
import urllib

from bs4 import BeautifulSoup

from w3lib.url import safe_url_string


# ASCII link for solved encoding problems —
# https://stackoverflow.com/a/40654295/5951529
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 — https://stackoverflow.com/a/11923803/5951529
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 —
# https://stackoverflow.com/a/3942100/5951529
remove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")
# https://stackoverflow.com/a/32451970/5951529
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 plugin

现在,在此基础上的代码,我写了崇高文字插件更换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 —
        # https://stackoverflow.com/a/40654295/5951529
        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 — https://stackoverflow.com/a/11923803/5951529
        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 —
        # https://stackoverflow.com/a/3942100/5951529
        remove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")
        # Final link — https://stackoverflow.com/a/32451970/5951529
        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. Using global Python environment of computer

我不觉得,我怎么能做到这一点。问题的例子,我可以找到:

2. Using Sublime Text environment

我安装

复制我w3lib目录从C:\Python36\Lib\site-packagesData\Packages崇高文本的目录。

我在崇高的文本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. Using variables in 2 files

比如我有KristinitaLuckyLink.pyKrisDuckDuckGo.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 — https://stackoverflow.com/a/4760517/5951529
        # 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 —
# https://stackoverflow.com/a/40654295/5951529
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 — https://stackoverflow.com/a/11923803/5951529
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 —
# https://stackoverflow.com/a/3942100/5951529
remove_duckduckgo_symbols = first_link.replace("/l/?kh=-1&uddg=", "")
# Final link — https://stackoverflow.com/a/32451970/5951529
final_link = (urllib.parse.unquote(remove_duckduckgo_symbols))
print(final_link)

我选择→我在崇高的文本控制台打印任何文字:

window.run_command( “kristinita_lucky_link”)

我不明白在崇高的文本控制台输出。


7.环境

操作系统和版本: 视窗10 LTSB企业64位的EN 崇高文字: 建立3126 蟒蛇: 3.6.0

python python-3.x sublimetext3 sublimetext sublime-text-plugin
4个回答
3
投票

错误:

bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?

最有可能来,因为崇高的文本被发现安装作为全球Python环境的一部分lxml - 这是编译不同版本的Python比ST采用一个 - 所以它不能加载它。

我们想要的是ST找到sublime-lxml依赖,你在你的问题挂钩。 “为什么找错了吗?”,你可能会问。很难肯定地说,但我认为OdatNurd's answer gives us some clues - 即ST认为由于某种原因,sys.path包括所有全球Python包。默认情况下,ST应该只使用它的可执行文件驻留,并在ST数据目录中的文件夹的软件包的文件夹。例如,我的系统上,在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段使用的路径,但它可能不是很容易找出哪一个,没有通过他们都在寻找。当使用的编译系统,用于对那些在path是插件用来加载其模块的一个很大的不同,因此,建立系统也应保持这一“修复”的影响。


3
投票

如果你想使用你的计算机上的Python版本,不与崇高交付,您可以使用以下命令崇高的:

window.run_command("exec", {"shell_cmd" : '<your command here>'})

这个命令可以让你崇高的外执行你的计算机上的应用程序。只需用您要执行的shell命令的<your command here>。输出将在升华的输出面板(终端)被返回。该输出面板是从崇高控制台不同。

你可以把你想在那里使用,并使用脚本(需要额外的Python模块)作为参数Python的路径。例如:

window.run_command("exec", {"shell_cmd" : 'C:\Python36\python.exe D:\Sublime Text 3 x64\Data\Packages\KristinitaLuckyLink\LuckyLink\LuckyLink.py'})

您需要虽然你的包分成两个文件。一个文件,该文件描述了你的包和崇高的内所需的命令。另一个文件(这应该是在你的包目录的子目录 - 从而不踩踏由崇高的插件)包含你的代码的其余部分。第二个文件是您导入不包括在崇高内部的Python的Python模块。另外,你需要找到一种方法来传输您要使用第二脚本工作的选择或串/ URL。

你可以看看我怎么在我的崇高包PlotGraph做到了。


2
投票

从位置的Python负荷模块它知道经由sys.path的,并且在卓异文本3 sys.path指出在几个地点只有(例如随卓异可执行文件,用户安装的软件包的当前用户的位置等的包的位置)。

为了从一个崇高的文本插件中访问全球安装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)

这特别增加了路径tosys.path如果它已不存在,而模块的进口和使用。

崇高包括Python中的自己独特的版本,特别是沙箱本身,以便它不是在对Python或任何Python包的任何版本都依赖被安装了所使用运行它的计算机上,这就是为什么它不这样做你默认。


1
投票

Yes, plugins can work with Python modules, that user install globally. You are not obligated introduce modules to your Sublime Text plugin.

Problems

1. Python的3.3兼容性

对于2018年开始:

全球所有的模块,你在你的插件使用,必须兼容与Python 3.3。

1.1. Argumentation

1.1.1. Sublime Text sys.path order

例如,我添加到Default.sublime-package存档文件0000.py。从Default.sublime-package模块由崇高的文本开始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')

凡路径 - 我的全球sys.path

>>> import sys; sys.path
['', 'C:\\Python36', 'C:\\Python36\\python36.zip', 'C:\\Python36\\DLLs', 'C:\\Python36\\lib', 'C:\\Python36\\lib\\site-packages']

我重新启动崇高文字→我在控制台中看到:

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 module

例如,我想在我的插件Python Google Search API PyPI将模块来使用。它与Python 3.6,但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)

我重新启动崇高文字→我得到same traceback,仿佛0000.py无法实施。

1.2. Situation on begin of 2018

见崇高文本论坛讨论:

我希望,在内部崇高的文本环境的Python 3.3将被替换到3.6或3.7下一个版本在最近的将来。


2.环境变量

如果你知道,可能不添加新的环境变量,请回答this question

2.1. Plugin code

您需要创建在您的PC环境变量中,其中价值 - 路径site-packages文件夹中。例如,我把它命名为PYTHONPACKAGES

您需要添加到您的代码行中OdatNurd answer

# PYTHONPACKAGES path:
# https://stackoverflow.com/a/4907053/5951529
# Disable duplicate paths:
# https://stackoverflow.com/a/42656754/5951529
site_packages = (os.environ['PYTHONPACKAGES'])
if site_packages not in sys.path:
    sys.path.append(site_packages)

2.2. Activation instructions

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


3.重新启动

对于发展过程:

您可能需要重新启动崇高的文本,如果你在site-packages文件夹或子文件夹更改的文件。

3.1. Example

→你→导入examplesashamodule到您的插件→从examplesashamodule文件夹→插件删除examplesashamodule将作为site-packages仍处于examplesashamodule文件夹开始崇高文本您安装从PIP site-packagesAutomaticPackageReloader包并不在这种情况下帮助。

您重新启动崇高文本→你在崇高的文本控制台中看到回溯,即ImportError: No module named 'examplesashamodule'

显然,在一个会话外部模块崇高文本缓存数据。

© www.soinside.com 2019 - 2024. All rights reserved.