python选项代码,是否使用-m选项执行Python代码

本文详细解释了Python的`-m`命令行选项与直接运行脚本之间的区别。当使用`-m`选项时,Python会导入并运行库模块作为脚本,这使得相对导入在包内工作正常。而直接运行脚本则不会考虑包结构。通过示例展示了`-m`如何处理包和模块,包括`__package__`和`__main__`变量的差异。使用`-m`运行包时,Python会查找并执行包内的`__main__.py`作为脚本。
摘要由CSDN通过智能技术生成

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

With this python code a.py:

if __name__ == "__main__":

print __package__

print __name__

I tested python -m a to get

""

__main__

whereas python a.py returns

None

__main__

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

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?

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?

解决方案

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

and

python -m foo.bar.baz

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

Demo:

$ 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__

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.

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.

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

For packages, you can create a __main__.py module and have that run when running python -m package_name; in fact that's 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__

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. It's name is then still set to __main__, and the module object is still stored in sys.modules['__main__'].

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值