【问题标题】:PYTHONPATH is not read by IPython when installed via Homebrew通过 Homebrew 安装时,IPython 不会读取 PYTHONPATH
【发布时间】:2020-04-21 11:59:26
【问题描述】:

我在干净的 macOS Catalina(虚拟机)上使用 Homebrew 安装了 IPython 和 Python 3。

$ brew install ipython

由于ipython 包依赖于python3 包,Homebrew 将ipythonpython3 一起安装。

$ brew info ipython 
ipython: stable 7.13.0 (bottled), HEAD
Interactive computing in Python
https://ipython.org/
/usr/local/Cellar/ipython/7.13.0 (2,905 files, 21.8MB) *
  Poured from bottle on 2020-04-15 at 18:48:22
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/ipython.rb
==> Dependencies
Required: python ✔, zeromq ✔
==> Options
--HEAD
    Install HEAD version
==> Analytics
install: 11,543 (30 days), 33,591 (90 days), 98,995 (365 days)
install-on-request: 5,404 (30 days), 15,768 (90 days), 49,364 (365 days)
build-error: 0 (30 days)

我希望这两个命令都从我的 shell 环境中读取 PYTHONPATH,因为 ipython 在由 pip3 install ipython 安装时有效。

但是使用 Homebrew 安装的 ipythonpython3 具有不同的 sys.path 设置。

$ which ipython
/usr/local/bin/ipython
$ which python3
/usr/local/bin/python3
$ ipython 
Python 3.7.7 (default, Mar 10 2020, 15:43:33) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import sys; sys.path                                                                                            
Out[1]: 
['/usr/local/Cellar/ipython/7.13.0/libexec/bin',
 '',
 '/usr/local/Cellar/ipython/7.13.0/libexec/lib/python3.7/site-packages',
 '/usr/local/Cellar/ipython/7.13.0/libexec/vendor/lib/python3.7/site-packages',
 '/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python37.zip',
 '/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
 '/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload',
 '/usr/local/lib/python3.7/site-packages',
 '/usr/local/Cellar/ipython/7.13.0/libexec/lib/python3.7/site-packages/IPython/extensions',
 '/Users/oxon/.ipython']

$ python3
Python 3.7.7 (default, Mar 10 2020, 15:43:33) 
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys; sys.path
['', '/Users/oxon/root-6.20.02/obj/lib', '/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/site-packages']

第一季度。为什么它们不同?

第二季度。这是预期的行为吗?

第三季度。为什么IPython在pip3 install ipython安装时会读取PYTHONPATH

【问题讨论】:

  • 而不是which ipython,考虑使用type ipythontype python3
  • 还要注意ipython只是一个普通的文本文件,你可以用more "$(which ipython)"查看
  • 另请注意,Python 读取为 $HOME/.ipython/profile_default/ipython_config.py,这可能会导致不同的行为。
  • 用 pyenv 和 pip 安装它

标签: python macos ipython homebrew


【解决方案1】:

ipython 的 Homebrew 配方中归结为 the following line

bin.env_script_all_files(libexec/"bin", :PYTHONPATH => ENV["PYTHONPATH"])

在调用ipython 可执行文件之前,它会创建/usr/local/bin/ipython 脚本,将PYTHONPATH 设置为IPython 正常工作所需的固定值(因为它的模块位于默认Python 模块目录之外):

#!/bin/bash
PYTHONPATH="/usr/local/Cellar/ipython/7.14.0/libexec/lib/python3.8/site-packages:/usr/local/Cellar/ipython/7.14.0/libexec/vendor/lib/python3.8/site-packages" exec "/usr/local/Cellar/ipython/7.14.0/libexec/bin/ipython" "$@"

它只是覆盖您设置的PYTHONPATH 值。您可以将脚本修改为:

PYTHONPATH="$PYTHONPATH:/usr/local/Cellar/...

这将使它附加到您的 PYTHONPATH 而不是完全覆盖它,但是当 Homebrew 软件包更新或重新安装时,该文件将被覆盖。因此,建议在 IPython 启动目录 ~/.ipython/profile_default/startup 中放置一个脚本,例如 root.py,如下所示:

import sys
sys.path.append('/Users/oxon/root-6.20.02/obj/lib')

当你使用pip安装ipython时,它的模块会进入默认的Python模块目录,无论是系统的还是用户的或者虚拟环境的,都不需要乱搞@ 987654337@ 让ipython 正常运行。

我会说 Q2 的答案因此可能是一个错误,您可以在 GitHub 上提交 Homebrew 的问题,尽管考虑到他们如何对待 @987654322,我不会屏住呼吸@。

【讨论】:

  • 感谢您回答我的 Homebrew 特定问题的精彩解释。正如您所写,https://homebrew.bintray.com/bottles/ipython-7.14.0.catalina.bottle.tar.gz 确实有一个 ipython bash 脚本,它在初始化 PYTHONPATH 后执行 ipython/7.14.0/libexec/bin/ipython
  • 确实,瓶子只是同一个 Homebrew 配方的预构建版本。
【解决方案2】:

第一季度。为什么它们(即sys.path)不同?

sys.path 的填充方式通常是: 1) 当前工作目录,然后是 2) PYTHONPATH 环境变量中列出的目录,然后是 3) 依赖于安装的默认路径,这些路径由 site 模块控制。 来自https://docs.python.org/3/using/cmdline.htmlPYTHONPATH:增加模块文件的默认搜索路径。 另见,例如, https://leemendelowitz.github.io/blog/how-does-python-find-packages.html https://realpython.com/lessons/module-search-path/ https://docs.microsoft.com/en-us/visualstudio/python/search-paths?view=vs-2019

因此,每个 python 安装都可能有自己的sys.path。 另外sys.path不需要等于PYTHONPATH

检查两个(或三个?)案例中的每一个案例的值并回发:

import os
print( 'PYTHONPATH = ', os.environ['PYTHONPATH'] )

例如,我在 Ubuntu 20.04 下有 spyder3 和 python3.8。在同一个 CLI 启动时,每个都有自己的 sys.path,两者都“派生”自同一个 PYTHONPATH

第二季度。这是预期的行为吗?

是的。

第三季度。为什么IPython在pip3 install ipython安装时会读取PYTHONPATH

请在 CLI 执行任一 python 之前发布 PYTHONPATH ($ echo $PYTHONPATH) 的值。不清楚他们是否正在阅读它的价值。

如果这有助于找到原因,请回帖。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    • 2012-10-11
    • 2022-09-23
    • 2019-01-08
    相关资源
    最近更新 更多