2012-06-29 16 views
2

我目前正在使用Python,并且对功能在__main__中列出的事实感到困惑。我一直在寻找多个python脚本来试图找到一个共同的主题,以确定哪些功能在__main__中有一席之地,但无济于事。在这里我有我自己的代码的示例。 firstfunctionanotherfunction是我的代码中唯一的两个函数。有关__main__在Python中的概念性查询

def main(argv): 

    firstinput="" 
    secondinput="" 

    if len(argv) < 3 or len(argv) > 3: 
     print """"Please set to: 
       metisfinal.main(metisfinal.py, firstinput, secondinput)"""" 
     return 
    else: 
     firstinput = argv[1] 
     secondinput = argv[2] 

    firstfunction(firstinput, dictionary) 
    anotherfunction(list, secondinput) 

if __name__ == "__main__": 
    main(sys.argv) 

(我认为)我知道的参数和__main__通话是正确的,但firstfunctionanotherfunction总是返回错误(因为他们的观点没有全局定义)。我确信这是由于对__main__的错误理解而产生的,因为我查看过的所有其他示例基本上都以相同的方式设置了__main__

什么构成列出在__main__特定功能?我偶然发现了一些Python代码,其中有30个以上的函数,但程序员只在__main__中列出了其中的2个函数。同样地,有时一个代码将具有类在主参数,像这样的(Project较早定义为对象类):

def main(argv): 

    filename = "" 
    outputfilename = "" 

    p = Project(filename, outputfilename, subdomainNames) 
    p.generateICs() 

if __name__ == "__main__": 
    main(sys.argv) 

在概念上,我无法理解为什么未列出的所有功能。 ..并不是所有的人都需要运行,或者是简单地初始化一些东西?

我看着非典型的代码?我错过了什么关键概念__main__?一旦我找到了__main__的功能,是否有特定的方法来格式化它们?

+0

“将函数放入'__main__'”是什么意思? – FogleBird

+0

@FogleBird我认为像在C或C++ void main等) – Denis

+0

@FogleBird对于我所看过的所有脚本,在'__main__'末尾再次列出了脚本中的多个函数我不理解为什么。我以为'__main__'只是一种通过一次调用来运行整个脚本的方法。 – Ason

回答

8

目前尚不清楚“__main__”中所列的含义。 __main__不是源文件中的实体。相反,如果您直接执行该模块,则该模块的名称为,名称为。当你做if __name__=="__main__"时,你告诉Python执行该块中的代码,当且仅当代码作为主模块被执行 - 也就是说,如果它是一个正在运行的程序。如果从其他模块导入模块,if __name__=="__main__"块中的代码将不会运行。

请注意,如果block中没有“list”函数。相反,您将常规程序代码放在您希望运行的那个块中。通常这段代码只是调用一个函数。通常人们称这种功能为main()。但__main__main之间没有特殊关系。 (通过将其保存为“snicklefritz.py”,然后在命令行做python snicklefritz.py说,)

def snicklefritz(): 
    # This function will be run when you run the program 
    print "You ran the program!" 

if __name__ == "__main__": 
    snicklefritz() 

尝试运行本程序:您可以调用函数任何你喜欢的。你会看到“你运行的程序!”打印。如果您创建一个单独的文件,并且该文件的格式为import snicklefritz,则不会打印该消息。

请注意,没有关于“列表功能”。例如,看一下这个程序:

print "This will always be printed!" 

if __name__ == "__main__": 
    print "This will only be printed if you run the file as a program!" 

这里if __name__=="__main__"块没有“名单”的任何功能。它只包含当文件作为脚本运行时运行的实际代码。不过,人们通常不会这样做,因为将代码放在一个单独的函数中而不是只是坐在那里“暴露”在函数之外会更加整洁。

至于其他功能,您可以在模块中定义您喜欢的任何其他功能,以便在该模块中使用,或由其他导入模块的模块使用。通常,模块中的大部分功能都不会在if __name__=="__main__"模块中使用,因为它们不会成为“主”功能的一部分。相反,它们将是其他功能,供其他代码使用。例如:

def otherFunc(x): 
    # Return x squared 
    return x**2 

def snicklefritz(): 
    # This function will be run when you run the program 
    print "You ran the program!" 

if __name__ == "__main__": 
    snicklefritz() 

otherFunc根本没有在模块中使用。没关系。可能有人会想要导入你的模块并自己使用otherFunc。并非每个功能都必须在同一个模块中使用,更不用说可以从if __name__=="__main__"块中调用。

+0

'__main__'实际上是一个模块;你甚至可以导入它。 –

+1

@Ignacio Woha确实从快速的'dir(__ main __)'看起来很空虚 - 它有什么好处? – Voo

+0

确实如此,但它不是源文件中的实体,就像函数或类一样。 OP似乎认为'__main__'是源代码中的“地方”。无论如何,将'__main__'作为模块导入是一个相当模糊的技术,在基本的Python用法中并不常见。 (例如,线程库等使用它。) – BrenBarn

3

您误解了__main__成语。

考虑下面的程序,保存在一个名为sum.py文件:

def read_numbers(): 
    n1 = int(raw_input()) 
    n2 = int(raw_input()) 
    return n1, n2 

def sum_numbers(i1, i2): 
    return i1+i2 

def print_sum(i1, i2, i3): 
    print "%d + %d = %d" % (i1, i2, i3) 

v1, v2 = read_numbers() 
sum = sum_numbers(v1, v2) 
print_sum(v1, v2, sum) 

它有三个功能 - 一个从标准输入读取两个数字,另一个对其求和,第三个打印操作。在定义函数之后,我将它们称为读取两个数字并打印其总和。相当简单。如果我执行它,我得到的是这样的:

$ python sum.py 
12 
34 
12 + 34 = 46 

现在,假设我需要写另一个程序,这将只读一个号码 - 对方号码居然中给出。因为我已经有一个sum_numbers()功能和print_sum()功能,我可以下跌诱惑重用sum模块,这是一件好事:

import sum 
MY_FIXED_NUMBER=3 
n = int(raw_input()) 
value = sum.sum_numbers(n, MY_FIXED_NUMBER) 
print_sum(n, MY_FIXED_NUMBER, value) 

太好了!但是,如果我执行它,我得到了什么?此:

$ python three_sum.py 
12 
34 
12 + 34 = 46 
12 
12 + 3 = 15 

WAT ?!该程序要求我输入两个数字,打印出他们的总和,然后要求输入第三个数字,这个数字正确的总和为3.我只是想要求第三个数字,并且只打印3的数字!发生了什么?

它发生了,当我导入一个模块(如import sum)时,它内部的所有代码都被执行。所以,我的模块有两部分,一部分定义可用于别处的有用功能(我将称其为定义部分),另一部分是以某种方式执行此功能以获得特定结果,所以我可以使用模块作为程序(我将调用执行部分)。执行部分始终执行。

幸运的是,Python有一招,让我只当模块进口执行执行部分。如果我输入一个Python文件,import,该模块将有一个名为__name__变量,其名称将是模块的原始名称:

>>> import sum 
12 
34 
12 + 34 = 46 
>>> sum.__name__ 
'sum' 

但是,如果我跑了Python文件作为脚本($ python sum.py) ,__name__变量将在那里,但具有不同的名称。假设我添加了一行如

print __name__ 

在我的sum.py的末尾。当我再次运行它,我得到了它:

$ python sum.py 
12 
34 
12 + 34 = 46 
__main__ 

在另一方面,如果我跑three_sum.pyprint __name__结果是方式不同:

$ python three_sum.py 
12 
34 
12 + 34 = 46 
sum 
12 
12 + 3 = 15 

是的,__name__变量的值当作为脚本运行文件是__main__

那么,这怎么能帮助我?这样:我将把模块的执行部分放在if的条件中。如果模块的名称是__main__,这是因为该文件正在作为脚本运行,其中$ python sum.py - 在这种情况下,我应该执行模块的执行部分。所以我sum.py模块将现在这种方式:

def read_numbers(): 
    n1 = int(raw_input()) 
    n2 = int(raw_input()) 
    return n1, n2 

def sum_numbers(i1, i2): 
    return i1+i2 

def print_sum(i1, i2, i3): 
    print "%d + %d = %d" % (i1, i2, i3) 

if __name__ == "__main__": 
    v1, v2 = read_numbers() 
    sum = sum_numbers(v1, v2) 
    print_sum(v1, v2, sum) 

如果我跑$ python sum.py,我得到和以前一样:

$ python sum.py 
12 
34 
12 + 34 = 46 

但是,如果我跑three_sum.py,一切都不同了:

$ python three_sum.py 
12 
12 + 3 = 15 

现在,按预期工作。它以这种方式工作,因为第一次执行时模块的名称是__main__,因此将执行if __name__ == "__main__"下的命令。然而,在第二次执行中,模块的名称是sum,因此if下的命令未执行。

即使您的文件设计需要进口,但它仍然是把你的文件的执行部分if __name__ == "__main__"下一个很好的做法,这样你的文件很容易适应,成为一个模块。

+0

哦,@BrenBarn以优秀的答案来到我面前:)我会离开我的,因为它有一个稍微不同的方法,但是。 – brandizzi

+0

+1这样的详细解释!谢谢。通过一切步骤(以及代码示例)逐步完成流程非常有帮助。我将重新审视这一次。 – Ason