【问题标题】:Why can't the Python launcher import in a script (with shebang), when it works in the interpreter?当 Python 启动器在解释器中工作时,为什么不能在脚本中导入(使用 shebang)?
【发布时间】:2017-03-30 17:47:54
【问题描述】:

我正在使用py Python 启动器,导入时发生了一些奇怪的事情。某些模块无法在脚本中导入 - 尽管使用 pip 安装并且可以在解释器中导入。不过,这里有一个关键点:它可以在没有 shebang 行的脚本中工作。

例如,此脚本有效:

import requests

但是这个没有:

#!/usr/bin/env python
import requests

这是为什么? shebang 在这里有什么不同?

【问题讨论】:

    标签: python windows shebang path-variables


    【解决方案1】:

    py 启动器实际上是 handles shebang lines even on Windows。这意味着运行脚本的 Python 版本可能会因 shebang 行而异。例如,#!/usr/bin/env python2 的 shebang 行将始终运行 Python 2,#!/usr/bin/env python3 将始终运行 Python 3。没有 shebang 行,py 假装 shebang 是 !python,它使用 its built-in rules for selecting a Python version 处理它(请参阅 Python 版本限定符 部分)。默认情况下,如果您安装了它,这将是 Python 2 的某个版本。

    不过,这就是让你绊倒的原因。如果 shebang 是专门的 !/usr/bin/env pythonpy 而不是 follows the PATH environment variable 来模仿 Linux 的 env 的行为(见最后一段),并且只有在此之后才会恢复正常行为。这意味着带有 shebang 可能的脚本在与py 通常调用的 Python 版本不同的 Python 版本下运行,具体取决于 PATH 中的内容。这就是这里发生的事情 - #!/usr/bin/env python 在路径上找到另一个 Python 版本,并使用它来代替。该版本可能没有安装您pip installed 的模块,因此可能会失败。

    由于您使用的是 py,因此您的 PATH 中不应有 python,因此从您的 PATH 中删除任何 Python 基本目录条目(例如 C:\Python35),或者确保 PATH 上的第一个 Python 是 py 使用的默认 Python,并且一切都应该正常工作。

    但是,为什么py 不尝试默认遵循路径(或者当shebang 是!python 时),但是,这是任何人的猜测。

    【讨论】:

    • 在支持的虚拟命令中,只有/usr/bin/env python被定义为搜索Path——并且只有在没有版本规范的情况下,即#! /usr/bin/env python3不会在Path搜索python3.exe(最近有人提交了一个关于这个的错误,所以它可能会在未来的版本中改变)。至于python,它是一个不搜索Path的虚拟命令。
    • 至于在Path 中没有python,这很好,也是安装程序的默认行为。但是python 仍然是运行您将在教程中看到的解释器的官方方式。在命令行中使用py 很方便,但仅适用于 Windows。
    • @eryksun 是的,我在答案中提到了这一点。 “如果 shebang 具体 !/usr/bin/env python[...]”。我也很清楚!pythonpy 的“虚拟命令”——我已经阅读了源代码。最后一段质疑为什么做出决定,而不是为什么发射器表达这种行为。当然,这个答案是关于 Windows py 启动器的——问题说明了很多。
    • @eryksun 当我遇到这个问题时,我刚刚将 Python 更新到 3.5 - 原来安装设置为将其添加到 PATH(我猜我勾选了这个框,认为它可能意味着启动器) .
    • 是您想知道为什么!python 不搜索Path。我告诉过你,它根本不是这样设计的。没有什么深奥或根本的问题。事实上,在最初的几次迭代中,甚至/usr/bin/env python 也没有搜索Path。这是后来添加的,尽管 Vinay 在第一个版本中已经编写了对它的底层支持。
    猜你喜欢
    • 1970-01-01
    • 2018-02-10
    • 2016-04-20
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    • 2019-07-14
    相关资源
    最近更新 更多