【问题标题】:Execute an installed Python package as a script?将已安装的 Python 包作为脚本执行?
【发布时间】:2011-05-02 07:07:00
【问题描述】:

有没有办法让包作为脚本执行?例如:

[~]# easy_install /path/to/foo.egg
...
[~]# python -m foo --name World
Hello World

我尝试在我的包中创建一个__main__.py 文件,但它没有被执行(我使用的是 Python 2.6)。引发以下错误:

foo is a package and cannot be directly executed

我的包的结构如下:

foo/
  setup.py
  foo/
    __init__.py
    __main__.py

运行python -m foo.__main__ --name World 按预期工作,但我更喜欢前一种执行方式。这可能吗?

【问题讨论】:

标签: python


【解决方案1】:

这是 Python 2.6 中的回归。见issue2571

执行包的能力从来都不是有意的,因为这样做 以各种微妙的方式中断导入。这实际上是一个错误 2.5 完全允许它,​​所以 2.6 不仅再次禁用它,而且还添加了一个测试以确保它保持禁用状态(2.4 正确 用 ImportError 拒绝它,就像 2.6 一样)。

您有几个选项,您可以始终指定 main 运行它:

$ python -m module.__main__

或者你可以编写一个 shell 脚本包装器来检测 python 版本,然后以不同的样式执行它。

或者您可以在命令行上执行代码,然后导入并运行模块,然后将其放入 shell 脚本中:

$ python -c "import module; module.main()"

在我自己的命令行项目中,我有两个可以捕获错误的 shell 脚本(python 未安装等),但 shell 脚本也会执行导入代码并检测是否已安装必要的模块并提示错误(带有有用的链接或安装文本)。

【讨论】:

  • 如果是这样,那么__main__.py 的目的是什么,它实际上是否在后续版本中保持禁用状态?
  • @benjimin 我不知道__main__.py在2.7之前的用途是什么,但是从2.7开始,它的使用得到了官方支持,如the 2.7 docs中所述。
【解决方案2】:

我认为这可能是 Python 2.6 的限制。我已经对其进行了测试,并且使用-m 选项执行一个包(在. 中或使用easy_install 从一个鸡蛋安装)在2.7 中可以正常工作,但在2.6 中不行。例如,在我的系统 (Ubuntu) 上,当前目录中有一个名为 pkg_exec 的测试包,而 __main__.py 只是打印 sys.argv

xx@xx:~/tmp/pkg_exec$ python2.6 -m pkg_exec
/usr/bin/python2.6: pkg_exec is a package and cannot be directly executed
xx@xx:~/tmp/pkg_exec$ python2.7 -m pkg_exec
['/home/xx/tmp/pkg_exec/pkg_exec/__main__.py']

另外,根据the 2.7 docs

在 2.7 版中更改:提供包名称以运行 __main__ 子模块。

【讨论】:

    【解决方案3】:

    是的,如果脚本有 __main__ 部分,您可以这样做。

    当然,如果是目录,则不能执行包。但是,如果您可以运行脚本本身(假设它以#!/usr/bin/python3 开头并以./script 运行它),您可以这样选择另一个解释器:

    /bin/python2 -v ../path/to/my/script status
    

    -v 用于解释器(如果需要),status 是脚本的参数。

    【讨论】:

    • 对不起,也许作者不是这个意思,但我回答了第一句话:“有没有办法让包作为脚本执行?”
    【解决方案4】:

    只要包在python路径上, 在脚本末尾添加。

    if __name__ == "__main__":
         call_script()
    
    $ python -m 模块名

    将运行模块,例如

    python -m 随机

    【讨论】:

    • 这不适用于包。 OP 知道模块的 -m 开关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 2013-07-22
    相关资源
    最近更新 更多