Python 中的__main__和__name__

2023-09-17 22:15:15

用C系列语言(C,C++,Java,C#等)编写的程序需要main()函数来指示执行的起点。

另一方面,在Python中,没有main()函数的概念,因为它是一种基于解释器的语言,可以在interactive shell中同样使用。 扩展名为.py Python 程序文件包含多个语句。Python 程序文件的执行从第一个语句开始。

Python 包含名为 __name__ 的特殊变量,该变量包含作为字符串执行的代码的范围。 __main__ 是执行顶级代码的顶级作用域的名称。

例如,在解释器 shell 中执行的代码的作用域将是__main__的,如下所示。

Python Shell

>>>__name__
'__main__'

所有函数和模块都将在解释器外壳__main___顶级范围内执行。

Python Shell

>>> def f1():
	print(__name__)
>>> f1()

甚至内部函数也在顶级范围内执行__main__:

Python Shell

>>> def f1():
	print(__name__)
	def f2():
		print(__name__)
	f2()
	
>>> f1()
__main__
__main__

Python 文件可以包含多个可以独立执行的函数和语句。例如,请考虑以下addition.py:

addition.py

def add(x,y):
    z=x+y
	print('add() executed under the scope: ', __name__)
    return z
x=input('Enter the first number to add: ')
y=input('Enter the secode number to add: ')
result = add(int(x),int(y))
print(x, '+', y,'=', result)
print('Code executed under the scope: ', __name__)

Python程序文件可以通过以下方式执行:

  1. 使用命令提示符/终端将 Python 文件作为脚本执行。
  2. 使用 import 语句将 Python 代码从一个文件导入到另一个文件
C:Python37> python addition.py
Enter the first number to add: 3
Enter the secode number to add: 3
add() executed under the scope: __main__
3 + 3 = 6
Code executed under the scope: __main__

如您所见,在顶级作用域下执行的addition.py __main__

addition.py文件可以用作另一个文件中的模块,也可以通过导入在交互式 shell 中用作模块。

让我们看看在交互式 shell 中导入 addition 模块时会发生什么。

Python Shell

>>> import addition
Enter the first number to add: 3
Enter the secode number to add: 3
add() executed under the scope:  addition
3 + 3 = 6
Code executed under the scope:  addition

上面,import 语句从第一个语句开始执行。但是,我们只想使用 add() 方法,不想执行其他语句。

在这里,我们可以使用特殊变量 __name__ 来检查范围并仅在 addition.py 文件从命令提示符/终端独立执行时才执行它的语句,而不是在将其导入其他文件/模块时执行。 重写addition.py,如下所示。

addition.py

def add(x, y):
    z=x+y
	print('add() executed under the scope: ', __name__)
    return z
if __name__ == '__main__':
    x=input('Enter the first number to add: ')
    y=input('Enter the secode number to add: ')
    result = add(int(x),int(y))
    print(x, '+', y,'=', result)
    print('Code executed under the scope: ', __name__)

上面,if 条件检查如果范围__main__则仅执行接受用户输入并添加它们的代码。

现在,让我们看看当我们在交互式 shell 中导入上述addition模块时会发生什么。

Python Shell

>>> import addition
>>> addition.add(3,3)
add() executed under the scope:  addition
6

您也可以使用 from import 语句,如下所示:

Python Shell

>>> from addition import add
>>> add(3,3)
add() executed under the scope:  addition
6

如您所见,由于我们使用 if 条件来检查范围,因此它在导入addition模块后不会执行用户输入代码,因为它在模块的作用域(即addition作用域)下执行。 它仅导入add()方法。当您在其他模块中导入addition模块时,也会发生同样的事情。

现在,让我们看看从命令提示符/终端执行它时会发生什么。

C:Python37> python addition.py
Enter the first number to add: 3
Enter the secode number to add: 3
add() executed under the scope: __main__
3 + 3 = 6
Code executed under the scope: __main__

如您所见,由于addition.py在顶级范围__main__中执行,它仍然执行相同的代码。

因此,name的值允许 Python 解释器确定模块是否旨在成为可执行脚本。如果其值为 main ,函数定义之外的语句将被执行。否则,模块的内容将填充在顶级模块(或解释器命名空间)中,而不使用可执行部分。

注意:从命令提示符/终端执行的 Python 脚本文件将在顶级作用域__main__作用域下执行。但是,导入模块将在模块自己的范围内执行。因此,顶级作用域将是__main__,第二个作用域将是模块的作用域。

因此,使用特殊变量__name__和顶级作用域__main__增加了可重用性。Python 脚本文件可以从命令提示符/三元作为独立脚本执行,也可以在作为模块导入时执行。