Python中的“样板”代码?

39 投票
8 回答
61347 浏览
提问于 2025-04-17 05:00

谷歌有一个关于Python的教程,他们把“模板代码”称为“不幸的”,并给出了一个例子:

#!/usr/bin/python

# import modules used here -- sys is a very standard one
import sys

# Gather our code in a main() function
def main():
  print 'Hello there', sys.argv[1]
  # Command line args are in sys.argv[1], sys.argv[2] ..
  # sys.argv[0] is the script name itself and can be ignored

# Standard boilerplate to call the main() function to begin
# the program.
if __name__ == '__main__':
  main()

我听说过“模板代码”被描述为“看起来重复的代码,为了得到某个结果而不断出现,这个结果似乎应该更简单一些”(例子)。

总之,在Python中,上面例子中被认为是“模板代码”的部分是:

if __name__ == '__main__':
  main()

现在,我有几个问题:

1) 在Python中,像上面提供的例子那样的模板代码,是否和我给出的定义是一样的?如果是的话,为什么?

2) 这段代码真的有必要吗?在我看来,不管有没有主方法,这段代码都能运行。使用这段代码有什么好处?真的更好吗?

3) 我们为什么要使用这段代码,它提供了什么服务?

4) 这种情况在Python中普遍存在吗?还有其他“模板代码”的例子吗?

哦,还有一个题外话的问题:在Python中使用命令行参数需要import sys吗?如果没有,它是怎么处理这些参数的?

8 个回答

3

使用“if main”检查的原因是,你可以有一个模块,在顶层运行一些代码(比如创建它要导出的常量、函数或类),而有些代码只有在作为脚本执行时才会运行(例如,进行功能测试)。

把后面的代码放在一个函数里是因为,如果不这样做,main()块里的局部变量会泄露到模块的作用域中,可能会引起混乱。

另外一种设计方式是,作为脚本执行的文件必须声明一个名为__main__()的函数,但这样就需要为语言添加一个新的特殊函数名,而__name__机制已经存在了。(而且这个机制是不能去掉的,因为每个模块都必须有一个__name__,而作为脚本执行的模块必须有一个“特殊”的名字,这是因为模块名的分配方式。)为了消除两行重复代码而引入两种机制来做同样的事情,通常每个应用程序还要两行重复代码,这样做似乎不太值得。

9

在这里,if __name__ == "__main__": 这个部分被称为“样板代码”,是因为它实现了一些在其他很多编程语言中是自动完成的功能。在Java或C++等语言中,当你运行代码时,程序会自动寻找一个叫main()的方法并执行它,如果找不到还会报错。而在Python中,程序会执行你文件里的所有代码,所以你需要特别告诉它去运行main()方法;一个简单的替代方法就是让运行main()方法成为默认行为。

因此,if __name__ == "__main__": 是一种常见的写法,其实可以更简短。你也可以选择其他的方式,比如:

if __name__ == "__main__":
  print "Hello, Stack Overflow!"

  for i in range(3):
    print i

  exit(0)

这样也是可以的;虽然我的例子有点搞笑,但你可以看到你可以在这里放入任何你想要的内容。Python的设计者选择了这种方式,而不是自动运行main()方法(这个方法可能根本不存在),大概是因为Python是一种“脚本”语言;你可以直接把一些命令写进文件里,运行它,这些命令就会执行。我个人更喜欢Python的这种方式,因为它让初学者更容易上手,而且在Python中,打印“Hello World”只需要一行代码,这总是很不错的。

26
  1. 这段话的意思是,每次你从命令行执行脚本的时候,都会重复这些内容。
  2. 如果你把主要的代码放在一个函数里,这样你就可以导入这个模块而不执行它。这在某些情况下很有用,也能让代码看起来更整洁。
  3. 我觉得这和第二点是一样的。
  4. Python通常能很好地避免写重复的代码。它的灵活性很高,所以在大多数情况下,你可以写代码来生成那些重复的部分,而不是直接写那些重复的代码。

题外话:

如果你不写代码来检查参数,它们就会被忽略。

撰写回答