难点和错误

我们在很多示例程序中都能看到主函数的内容被放在条件表达式if __name__ == __main__:内,比如象balladWithIF.py这个样子:

# --------------------------------------- balladWithIF ----------------------------------

def farmerAndDragon():
    print("老龙恼怒闹老农,老农恼怒闹老龙。农怒龙恼农更怒,龙恼农怒龙怕农")

def skyAndWater():
    print("天连水,水连天,水天一色望无边。蓝蓝的天似绿水,绿绿的水如蓝天。到底是天连水,还是水连天?")

if __name__ == '__main__':
    farmerAndDragon()
    skyAndWater()

而我们到目前为止一直是象balladWithoutIF.py这样直接写

# ----------------------------------- balladWithoutIF -------------------------------

def melon():
    print("金瓜瓜,银瓜瓜,瓜棚上面结满瓜")

def tower():
    print("白石塔,白石搭。白石搭白塔,白塔白石搭")

melon()
tower()

为什么要加上if __name__ == __main__这个条件呢?

分别在程序balladWithIF.py里和程序balladWithoutIF.py里点击运行按钮,balladWithIF.py的运行结果为:

老龙恼怒闹老农,老农恼怒闹老龙。农怒龙恼农更怒,龙恼农怒龙怕农

天连水,水连天,水天一色望无边。蓝蓝的天似绿水,绿绿的水如蓝天。到底是天连水,还是水连天?

balladWithoutIF.py的结果是:

金瓜瓜,银瓜瓜,瓜棚上面结满瓜

白石塔,白石搭。白石搭白塔,白塔白石搭

貌似没什么区别呀!那加这个条件判断不是多此一举么?

不是多此一举,没区别是因为是在自己的程序里运行的自己。当自己程序定义的函数被其他程序调用时就能看出区别来了。

比如有一个叫做tongueTwister.py的程序就在程序内分别调用了balladWithIF.pyballadWithoutIF.py里定义的函数。当然调用前需要把这两个程序引入进tongueTwister.py,并确保把balladWithIF.pyballadWithoutIF.py所在的路径放在python解释器的搜索范围内(视频里有提怎么放): 

# -------------------------------- tougueTwister.py -------------------------------

import balladWithIF
import balladWithoutIF

print("绕口令:")
balladWithIF.farmerAndDragon()
balladWithIF.skyAndWater()
balladWithoutIF.melon()
balladWithoutIF.tower()

点击运行tongueTwister.py的按钮后,可以看到运行结果为: 

金瓜瓜,银瓜瓜,瓜棚上面结满瓜

白石塔,白石搭。白石搭白塔,白塔白石搭

绕口令:

老龙恼怒闹老农,老农恼怒闹老龙。农怒龙恼农更怒,龙恼农怒龙怕农

天连水,水连天,水天一色望无边。蓝蓝的天似绿水,绿绿的水如蓝天。到底是天连水,还是水连天?

金瓜瓜,银瓜瓜,瓜棚上面结满瓜

白石塔,白石搭。白石搭白塔,白塔白石搭

跟预想的不一样,预想的结果应该是:

绕口令:

老龙恼怒闹老农,老农恼怒闹老龙。农怒龙恼农更怒,龙恼农怒龙怕农

天连水,水连天,水天一色望无边。蓝蓝的天似绿水,绿绿的水如蓝天。到底是天连水,还是水连天?

金瓜瓜,银瓜瓜,瓜棚上面结满瓜

白石塔,白石搭。白石搭白塔,白塔白石搭

“绕口令:……”前面那两行是哪里冒出来的?

实际上Python解释器一“看”到import ballatWithIF马上就去调ballatWithIF.py的主函数来执行,显然条件判断(if __name__ == '__main__':)没有被满足,什么也没做地去解释下一条语句import balladWithoutIF了。

import balladWithoutIF这里就不同喽,调balladWithoutIF的主函数来执行:

melon()
tower()

可见完全没用设防,马上执行!这也为什么运行结果里“绕口令:……”之前会有:

金瓜瓜,银瓜瓜,瓜棚上面结满瓜

白石塔,白石搭。白石搭白塔,白塔白石搭

由此可见,加if __name__ == '__main__':的条件判断是个好习惯。万一您在这个程序定义的函数被其他程序引用了呢?

最后就是__name__是啥?看外表(前后都有俩下划线)是私有变量,确实是!

如果在本程序内(比如ballotWithoutIF.py)加一句:

print(__name__)

这句对应的运行结果会是”__main__”。

如果在本程序内引用其他程序的__name__,则值是其他程序的名称。比如在tongueTwister.py内加一条:

print(ballotWithoutIF.__main__)

这条语句对应的运行结果是ballotWithoutIF.py的名字ballotWithoutIF 

这也是为什么在tongueTwister.py里,Python解释器解释到import ballotWithIF时调来ballotWithIF.py

if __name__ == '__main__':
    farmerAndDragon()
    skyAndWater()

执行。在tongueTwister.py里,ballotWithIF.py__name__’ballotWithIF’,显然与’__main__’不相等,不满足if语句成立的条件,所以Python解释器只好什么也没做地越过去解释import ballotWithIF后面的语句去了。