我目前正在使用Python,并且对__main__
中列出的函数这一事实感到困惑。我一直在查看多个 python 脚本,试图找到一个共同的主题,即哪些函数值得在__main__
中占有一席之地,但无济于事。在这里,我有一个我自己的代码示例。 firstfunction
和 anotherfunction
是我的代码中仅有的两个函数。
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__
调用是正确的,但firstfunction
和anotherfunction
总是返回错误(因为它们的参数不是全局定义的)。我肯定这是由于对__main__
的错误理解引起的,因为我看过的所有其他例子基本上都以相同的方式设置__main__
。
什么构成在__main__
中列出特定功能?我偶然发现了一些包含 30 多个函数的 Python 代码,但程序员只列出了其中的 2 个函数 __main__
.同样,有时代码会在主参数中包含类,例如这个(Project
之前定义为对象类):
def main(argv):
filename = ""
outputfilename = ""
p = Project(filename, outputfilename, subdomainNames)
p.generateICs()
if __name__ == "__main__":
main(sys.argv)
从概念上讲,我不明白为什么没有列出所有功能......它们不需要全部运行还是__main__
只是在初始化某些东西?
我在看非典型代码吗?我缺少哪些关键的__main__
概念?一旦我找到了要放入__main__
的功能,是否有特定的方法来格式化它们?
不清楚你所说的"列在__main__
"是什么意思。 __main__
不是源文件中的实体。 相反,它是模块的名称,如果你直接执行它。 当你做if __name__=="__main__"
时,你告诉Python执行该块中的代码,当且仅当代码作为主模块执行时,---也就是说,如果它是一个正在运行的程序。 如果模块是从另一个模块导入的,则不会运行if __name__=="__main__"
块中的代码。
请注意,您不会在该 if 块中"列出"函数。 相反,您将常规程序代码放在要运行的块中。 通常,此代码只调用一个函数。 人们通常称该函数为main()
。 但是__main__
和main
之间没有特殊的关系。 你可以随心所欲地调用该函数:
def snicklefritz():
# This function will be run when you run the program
print "You ran the program!"
if __name__ == "__main__":
snicklefritz()
尝试运行此程序(例如,将其另存为"snicklefritz.py",然后从命令行执行python snicklefritz.py
)。 你会看到打印的"你运行了程序!"。 相反,如果您创建一个单独的文件,该文件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__"
块中使用,因为它们不会成为"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__"
块调用了。
你误解了__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
寺院?!程序要求我输入两个数字,打印它们的总和,然后要求第三个数字,该数字正确求和为 3。我只是想被要求提供第三个数字,并且只是用 3 打印总和!发生了什么事?
碰巧,当我导入一个模块(例如import sum
)时,其中的所有代码都会被执行。因此,我的模块有两个部分,一部分定义了可以在其他地方使用的有用函数(我称之为定义部分),另一部分是它以某种方式执行此函数以获得特定结果的部分,因此我可以将该模块用作程序(我将称之为执行部分)。执行部分始终执行。
幸运的是,Python 有一个技巧,允许我仅在模块未导入时才执行执行部分。如果我导入一个带有 import
的 Python 文件,该模块将有一个名为 __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.py
,print __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__"
下仍然是一种很好的做法,这样您的文件就很容易适应成为一个模块。