是否使用 -m 选项执行 Python 代码 [英] Execution of Python code with -m option or not

查看:19
本文介绍了是否使用 -m 选项执行 Python 代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

python 解释器具有 -m module 选项,可以将库模块 module 作为脚本运行".

The python interpreter has -m module option that "Runs library module module as a script".

使用这个python代码a.py:

With this python code a.py:

if __name__ == "__main__":
    print __package__
    print __name__

我测试了 python -m a 得到

"" <-- Empty String
__main__

python a.py 返回

None <-- None
__main__

对我来说,这两个调用似乎是相同的,除了使用 -m 选项调用时 __package__ 不是 None .

To me, those two invocation seems to be the same except __package__ is not None when invoked with -m option.

有趣的是,使用python -m runpy a,我得到与python -m a 相同的python 模块编译为a.pyc.

Interestingly, with python -m runpy a, I get the same as python -m a with python module compiled to get a.pyc.

这些调用之间的(实际)区别是什么?他们之间有什么优缺点吗?

What's the (practical) difference between these invocations? Any pros and cons between them?

此外,David Beazley 的 Python Essential Reference 将其解释为-m 选项将库模块作为脚本运行,该脚本在执行主脚本之前在 __main__ 模块内执行".什么意思?

Also, David Beazley's Python Essential Reference explains it as "The -m option runs a library module as a script which executes inside the __main__ module prior to the execution of the main script". What does it mean?

推荐答案

当您使用 -m 命令行标志,Python 会为你导入一个模块或包,然后将其作为脚本运行.当您不使用 -m 标志时,您命名的文件将作为只是一个脚本运行.

When you use the -m command-line flag, Python will import a module or package for you, then run it as a script. When you don't use the -m flag, the file you named is run as just a script.

当您尝试运行包时,区别很重要.有很大的区别:

The distinction is important when you try to run a package. There is a big difference between:

python foo/bar/baz.py

python -m foo.bar.baz

在后一种情况下,foo.bar 被导入,相对导入将在 foo.bar 作为起点正常工作.

as in the latter case, foo.bar is imported and relative imports will work correctly with foo.bar as the starting point.

演示:

$ mkdir -p test/foo/bar
$ touch test/foo/__init__.py
$ touch test/foo/bar/__init__.py
$ cat << EOF > test/foo/bar/baz.py 
> if __name__ == "__main__":
>     print __package__
>     print __name__
> 
> EOF
$ PYTHONPATH=test python test/foo/bar/baz.py 
None
__main__
$ PYTHONPATH=test python -m foo.bar.baz 
foo.bar
__main__

因此,Python 在使用 -m 开关时必须真正关心包.一个普通的脚本永远不能成为一个包,所以 __package__ 被设置为 None.

As a result, Python has to actually care about packages when using the -m switch. A normal script can never be a package, so __package__ is set to None.

但是运行一个包或模块inside一个带有-m的包,现在至少有一个包的可能性,所以__package__ 变量设置为字符串值;在上面的演示中,它被设置为 'foo.bar',对于不在包内的普通模块,它被设置为空字符串.

But run a package or module inside a package with -m and now there is at least the possibility of a package, so the __package__ variable is set to a string value; in the above demonstration it is set to 'foo.bar', for plain modules not inside a package it is set to an empty string.

至于 __main__ module,Python 导入正在运行的脚本,就像导入常规模块一样.创建一个新的模块对象来保存全局命名空间并存储在 sys.modules['__main__'] 中.这就是 __name__ 变量所指的内容,它是该结构中的一个键.

As for the __main__ module, Python imports scripts being run as it would import regular modules. A new module object is created to hold the global namespace and is stored in sys.modules['__main__']. This is what the __name__ variable refers to, it is a key in that structure.

对于包,你可以在里面创建一个 __main__.py 模块,并在运行 python -m package_name 时运行它;事实上,这是您可以将包作为脚本运行的唯一方式:

For packages, you can create a __main__.py module inside and have that run when running python -m package_name; in fact that is the only way you can run a package as a script:

$ PYTHONPATH=test python -m foo.bar
python: No module named foo.bar.__main__; 'foo.bar' is a package and cannot be directly executed
$ cp test/foo/bar/baz.py test/foo/bar/__main__.py
$ PYTHONPATH=test python -m foo.bar
foo.bar
__main__

因此,当使用 -m 命名要运行的包时,Python 会查找该包中包含的 __main__ 模块并将其作为脚本执行.然后它的名称仍然设置为 '__main__' 并且模块对象仍然存储在 sys.modules['__main__'] 中.

So, when naming a package for running with -m, Python looks for a __main__ module contained in that package and executes that as a script. Its name is then still set to '__main__' and the module object is still stored in sys.modules['__main__'].

这篇关于是否使用 -m 选项执行 Python 代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆