__main__.py是否需要“如果__name__ =='__main__'”?

时间:2020-04-24 21:04:52

标签: python python-3.x

在具有__main__.py而不是

的项目中
# __main__.py
# def main...

if __name__ == "__main__":
    main()

...可以这样做吗?

# __main__.py
# def main...

main()

编辑:

@ user2357112-supports-Monica的论点对我来说很有道理,因此我回过头来查找一直给我带来问题的库,导致我仍然添加if __...行。正在调用python -m pytest --doctest-modules

也许这是唯一在运行__main__.py时出错的地方吗?也许那是个错误?

通过将第一个示例放在__main__.py中的docs中来复制:

――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― package/__main__.py ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
package/__main__.py:58: in <module>
    args = parser.parse_args()
/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/argparse.py:1755: in parse_args
    args, argv = self.parse_known_args(args, namespace)
/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/argparse.py:1787: in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/argparse.py:2022: in _parse_known_args
    ', '.join(required_actions))
/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/argparse.py:2508: in error
    self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/argparse.py:2495: in exit
    _sys.exit(status)
E   SystemExit: 2
--------------------------------------------------------------------------------------- Captured stderr ---------------------------------------------------------------------------------------
usage: pytest.py [-h] [--sum] N [N ...]
pytest.py: error: the following arguments are required: N

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Results (4.23s):

1 个答案:

答案 0 :(得分:3)

可以在大多数常规脚本中跳过if __name__ == '__main__'保护,而不仅仅是__main__.py。保护措施的目的是,如果文件作为模块导入而不是作为程序的入口点运行,则不使特定代码运行,但将__main__.py导入模块通常无论如何都会使用它。

即使使用multiprocessing,您也可能认为您需要一个if __name__ == '__main__'警卫,但是对于__main__.py而言,它实际上并没有帮助。通常说来,在{awn}或forkserver模式下的multiprocessing会将__main__脚本作为模块导入,但这是对实际行为的简化。特别是,实际行为的一部分是,如果生成模式检测到主脚本是__main__.pyit just doesn't try to load the original __main__ at all

# __main__.py files for packages, directories, zip archives, etc, run
# their "main only" code unconditionally, so we don't even try to
# populate anything in __main__, nor do we make any changes to
# __main__ attributes
current_main = sys.modules['__main__']
if mod_name == "__main__" or mod_name.endswith(".__main__"):
    return

在我测试它时,forkserver模式也没有加载__main__.py,但是forkserver的代码路径略有不同,我不确定它决定跳过__main__.py的地方。

(这在不同的Python版本上可能有所不同-我只检查了3.8.2。)


也就是说,使用if __name__ == '__main__'防护程序没有什么错误。不使用它比使用它具有更多奇怪的边缘情况,并且有经验的读者会对它的缺席而不是它的存在感到困惑。即使在__main__.py中,我可能仍会使用防护罩。

如果您确实出于某种原因确实想导入__main__.py,也许想对在那里定义的功能进行单元测试,那么您将需要保护。但是,将值得导入的所有内容移出__main__.py并移到另一个文件中可能更有意义。