【发布时间】:2011-07-29 12:30:43
【问题描述】:
我有很多简单的脚本来计算一些东西。它们仅由一个模块组成。
我应该为它们编写主要方法并使用if __name__ 构造调用它们,还是直接将其转储到那里?
这两种方法的优点是什么?
【问题讨论】:
标签: python
我有很多简单的脚本来计算一些东西。它们仅由一个模块组成。
我应该为它们编写主要方法并使用if __name__ 构造调用它们,还是直接将其转储到那里?
这两种方法的优点是什么?
【问题讨论】:
标签: python
我总是编写一个main() 函数(适当命名),除了命令行解析和对main() 的调用之外什么都没有放在if __name__ == '__main__' 块中。这是因为无论我最初期望该脚本是多么愚蠢、琐碎或单一用途,我总是想在以后的某个时间从另一个模块调用它。
要么我今天花时间把它变成一个可导入的模块,要么花额外的时间在几个月后重构它,当我想将它重用于其他东西时。
总是。
每次。
我已经停止与之抗争,并从一开始就抱着这种期望开始编写我的代码。
【讨论】:
if __name__ 屏障调用的模块级 main() 函数。这也是创建 console_script 入口点的好模式,例如'console_scripts': ['myscript=foo.mybar:main']
ifmain sn-p 来插入 "if __name__..." 部分。
好吧,如果你这样做:
# your code
然后import your_module 将执行您的代码。相反,这样:
if __name__ == '__main__':
# your code
导入不会运行代码,但会将解释器定位到该文件。
如果脚本运行的唯一方法是手动打开解释器,那绝对没有区别。
当您拥有一个库(或重用脚本中的定义)时,这一点变得很重要。
在定义之外或在if __name__ 保护之外的库中添加代码会在导入时运行代码,让您初始化库所需的内容。
也许您希望您的库也具有一些可运行的功能。也许是测试,或者像 Python 的 SimpleHTTPServer 之类的东西(它带有一些类,但你也可以运行该模块,它会启动一个服务器)。您可以使用 if __name__ 子句实现双重行为。
epydoc 之类的工具导入模块以访问文档字符串,因此在您只想生成 HTML 文档时运行代码并不是真正的意图。
【讨论】:
其他答案很好,但我想添加一个示例,说明您可能希望能够导入它的原因:单元测试。如果你有几个函数然后if __name__=="__main__":,你可以导入模块进行单元测试。也许你在这方面做得比我好,但我发现我的“不可能有任何错误的简单脚本”往往有我在单元测试中发现的错误。
【讨论】:
if __name__ 构造可以让您轻松地在其他 Python 脚本中重用模块中的函数和类。如果你不这样做,那么模块中的所有内容都会在imported 时运行。
如果脚本中没有您想要重用的内容,那么当然,只需将其全部转储到那里即可。我有时会这样做。如果您以后决定要重用某些代码,我发现 Python 几乎是最简单的语言,可以在不破坏代码的情况下重构代码。
【讨论】:
为了更好地解释 Python 的“主要守卫”习语的目的:
【讨论】: