作为脚本执行已安装的Python包?

时间:2010-10-29 08:11:48

标签: python

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

[~]# 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按预期工作,但我更喜欢以前的执行方式。这可能吗?

4 个答案:

答案 0 :(得分:32)

这是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脚本也将执行导入代码并检测是否已安装必要的模块并提示错误(使用有用的链接或安装文本)。

答案 1 :(得分:4)

我认为这可能是Python 2.6的限制。我已经对它进行了测试,并且使用.选项执行包(在-m中或使用easy_install从egg安装)可以在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__子模块。

答案 2 :(得分:0)

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

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

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

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

答案 3 :(得分:-4)

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

if __name__ == "__main__":
     call_script()
$ python -m module_name  

将运行模块,例如

python -m random