将site-packages文件夹正确添加到Sublime Text 3的sys.path中

3

1. 概述

我不明白如何让 全局 site-packages 路径 在每次启动 Sublime Text 3 时添加到 Sublime Text 3 的 sys.path 中。


2. 原因

我希望在 Sublime Text 插件中可以使用全局安装的包。

更多信息请参见 Sublime Text 插件开发中的全局 Python 包 问题。


3. 示例

我的插件示例:

import os
import sublime_plugin
import sys

from duckduckgo import query  # noqa
from pygoogling.googling import GoogleSearch  # noqa

# Any actions

需要翻译的内容:

这里有两个Python模块duckduckgopygoogling.googling,它们都在site-packages文件夹中。

实际插件示例


4. 未能帮助

4.1. 手动添加路径到控制台

我打开Sublime Text控制台 → 我将以下内容粘贴到其中:

import sys; sys.path.append('C:\Python36\Lib\site-packages')

现在:

>>> 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\\Lib\\site-packages']

我重新启动了Sublime Text→ 我打开了Sublime Text控制台:
>>> 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']

环境变量是手动添加的,在每次重启后都会被清除。

4.2. 使用 PYTHONPATH

我的解释器中的 PYTHONPATH 用户变量:

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

我修改了我的插件:

import os
import sublime_plugin
import sys

sys.path.append((os.environ['PYTHONPATH']))

from duckduckgo import query  # noqa
from pygoogling.googling import GoogleSearch  # noqa

# Any actions

现在:

>>> 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']

但是,Sublime Text不接受来自site-packages的模块:

reloading plugin KristinitaLuckyLink.KristinitaLuckyLink
Traceback (most recent call last):
  File "D:\Sublime Text Build 3143 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 "D:\Sublime Text Build 3143 x64 For Debug\sublime_plugin.py", line 915, in load_module
    exec(compile(source, source_path, 'exec'), mod.__dict__)
  File "D:\Sublime Text Build 3143 x64 For Debug\Data\Packages\KristinitaLuckyLink\KristinitaLuckyLink.py", line 40, in <module>
    from duckduckgo import query  # noqa
ImportError: No module named 'duckduckgo'

4.3. site-packages环境变量

我按照 Anthony Perrot的答案 修改了我的插件:

import os
import sublime_plugin
import sys

python_environment_variable = (os.environ['PYTHONPATH'])
sys.path.append(python_environment_variable)

site_packages = next(p for p in python_environment_variable if 'site-packages' in p)
sys.path.append(site_packages)

from duckduckgo import query  # noqa
from pygoogling.googling import GoogleSearch  # noqa

# Any actions

我在控制台中遇到了 StopIteration 异常:

reloading plugin KristinitaLuckyLink.KristinitaLuckyLink
Traceback (most recent call last):
  File "D:\Sublime Text Build 3143 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 "D:\Sublime Text Build 3143 x64 For Debug\sublime_plugin.py", line 915, in load_module
    exec(compile(source, source_path, 'exec'), mod.__dict__)
  File "D:\Sublime Text Build 3143 x64 For Debug\Data\Packages\KristinitaLuckyLink\KristinitaLuckyLink.py", line 36, in <module>
    site_packages = next(p for p in python_environment_variable if 'site-packages' in p)
StopIteration

5. 工作了,但出乎意料

5.1. 工作示例

我将新的环境变量添加到我的操作系统中,例如:

PYTHONPACKAGES=C:\Python36\Lib\site-packages

其中:

并且 修改我的插件:

import os
import sublime_plugin
import sys

sys.path.append((os.environ['PYTHONPACKAGES']))

from duckduckgo import query  # noqa
from pygoogling.googling import GoogleSearch  # noqa

# Any actions

插件将会成功运行。

5.2. 不符合预期的原因

每个下载我的插件的用户都需要为操作系统添加PYTHONPACKAGES环境变量,并可能需要重新启动操作系统。

如果插件的用户不需要添加环境变量就可以使用插件,那将是非常好的。

期望的行为:用户安装插件→ 用户可以在不进行额外设置的情况下使用插件。


6. 不要提供

  1. 请不要建议我不使用全局模块,而是需要将外部模块集成到插件文件夹中。

1
你担心每个使用你的软件包的用户都需要设置环境变量,以便Sublime可以看到你的软件包,而你应该担心的是,每个使用你的软件包的用户都必须首先安装Python 3.3,然后再安装你的软件包想要使用的模块。 - OdatNurd
@OdatNurd:感谢您的评论。//是的,我知道,用户需要安装Python和Python模块。但是它很简单 — pip install examplemodule。//每个使用您软件包的用户都必须安装Python 3.3 — 是的,Sublime Text软件包的所有模块都必须与Python 3.3兼容,但全局用户可以安装更高版本的Python。我使用最新稳定版本(当时的3.6.4)。谢谢。 - Саша Черных
我的意思是,如果用户必须手动安装Sublime之外的库才能使您的软件包正常工作,那么让他们设置一个环境变量也不会太麻烦吧? - OdatNurd
@OdatNurd:1. 添加新的环境变量并重新启动 - 对用户来说是额外的工作。如果不可能,可以在没有它的情况下使用插件 - 没问题;但如果可能的话,插件开发人员需要让用户的生活更轻松。// 2. PYTHONPATH 变量包含所有安装 Python 的用户。site-packages PYTHONPATH 的一部分。如果可以不添加新的环境变量,而是使用已经存在的 PYTHONPATH,那就太好了。谢谢。 - Саша Черных
我在你提供的问题中的答案告诉了你如何在启动时将某个东西添加到路径中(好吧,是插件加载时间,但这大概是你可以从Sublime中得到的最接近的答案了)。你应该问的问题不是“我怎样才能让它在启动时添加到路径中”,而更多的是“我应该在启动时添加什么路径”,我想。如果你能弄清楚这一点,另一部分就更容易了。 - OdatNurd
1个回答

1
您也可以使用以下方法来完成这个任务:

import site

# if outside of a sublime text plugin class
all_views = sublime.active_window().views()
# or if inside use the 'view' variable, skip to line 9 and change 
# all_views[0].settings to view.settings

if len(all_views) > 0:
    external_python_path = all_views[0].settings().get("external_python_path")

    sp = site.getsitepackages(external_python_path)
    sp = [x for x in sp if "site-packages" in x.lower()]
    sys.path.append(sp)

然后在您的Preferences.sublime-settings文件中,您需要添加一个key:value,如下:

{
    "somekey": "somevalue",
    ...,
    "external_python_path": "path_to_python folder excluding the python.exe"
}

Tushortz,抱歉,我需要使用你的Python代码创建Sublime Text插件,还是我需要你的代码来使用其他东西?谢谢。 - Саша Черных

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接