关于python:main()函数在运行脚本时不运行

main() function doesn't run when running script

1
2
3
4
#! /usr/bin/python

def main():
    print("boo")

当我尝试在Python3.3中运行它时,这段代码什么也不做。没有任何错误。怎么了?

1
2
3
4
[tim@tim-arch ~]$ gvim script
[tim@tim-arch ~]$ sudo chmod 775 script
[tim@tim-arch ~]$ ./script
[tim@tim-arch ~]$


您仍然需要调用函数。

1
2
3
4
def main():  # declaring a function just declares it - the code doesn't run
    print("boo")

main()  # here we call the function


我假设您想要做的是在从命令行执行脚本时调用print函数。

在python中,您可以通过检查__main____name__变量来确定包含一段代码的脚本是否与最初启动的脚本相同。

1
2
3
4
#! /usr/bin/python

if __name__ == '__main__':
    print("boo")

只有这些代码行:

1
2
def main():
    print("boo")

您定义的是一个函数,而不是实际调用它。要调用函数main(),需要这样调用它:

1
main()


您需要调用该函数,将脚本更新为

1
2
3
4
5
6
7
#! /usr/bin/python

def main():
    print("boo")

#call it
main()

在Python中,如果您希望编写一个脚本来按顺序执行一系列小任务,那么绝对不需要编写包含这些小任务的函数。只需将每个字符单独放在一行上;或者使用像;这样的表达式分隔符(不推荐使用,但您可以这样做),同样:

1
2
3
4
task1
task2
task3
task4

1
task1; task2; task3; (again **not** really recommended, and certainly not pythonic)

在您的案例中,您的代码可以转换为如下类型:

1
2
3
print('boo')
print('boo2')
print('boo3')

在没有main()方法的情况下,它仍然可以像您期望的那样工作,因为它们是按顺序评估的。

请注意,您可能希望为这些任务系列创建函数的原因是:

  • 为了(向代码的客户机)提供一个好的接口,
  • 或封装重复逻辑
  • 也许还有更多的用途,但这是我能想到的第一个方法,并证明我的观点。

现在,如果您觉得有必要用其他编程语言编写类似于main()方法的代码,那么请使用以下python习惯用法(如其他用户目前所述):

1
2
if __name__ == '__main__':
    doSomething()

以上工作如下:

  • 当您使用一个python模块import时,它会得到一个string(通常是导入它的名称)指定为它的__name__属性。
  • 直接执行脚本(通过调用python vm并将脚本的名称作为参数传递)时,__name__属性设置为__main__
  • 因此,在使用上述习惯用法时,既可以随意使用脚本作为可插拔模块,也可以直接执行脚本,直接对if __name__ == '__main__':下的一系列表达式进行计算。

如果您觉得有必要深入了解更多信息,我的资料来源如下:

  • python文档:模块
  • python文档:将模块作为脚本执行
  • python文档:数据模型(搜索__name__)

如果你发现其他的答案令人困惑或害怕,这里有一个寓言,希望能有所帮助。看看下面的python程序:

1
a = 34

当它运行时,它会做一些事情:在退出脚本之前,python了解到有一个变量a,它的值是整数34。它对这些信息没有任何作用,但它是一个完整的程序,可以做一些事情。但是,为了让它产生一些实际的价值,它需要与环境交互。它与这个值有什么关系?它可以创建34个目录,或者ping数据中心的第34个服务器,或者检查数据库中最新的34个用户的密码强度,或者打印一些东西。

1
2
a = 34
print(a)

以下程序在某种意义上与第一个程序非常相似。

1
2
3
def b():
    a = 34
    print(a)

当您运行这个程序时,它会做一些事情:python现在知道有一个名为b的函数,它不接受任何参数,并且它包含一些语法上有效的python代码,当其他代码调用它时,它会运行这些代码,但实际上它还没有对这些代码做任何事情。为了观察函数中代码产生的任何值,必须实际调用它:

1
b()

(顺便说一句,可能还要注意函数声明b中的局部变量a与同名的全局变量不同。)