Python学习: Python 中的 if __name__ == '__main__' '__file__'

博客介绍了不同编程语言的程序入口,重点讲解Python。Python是脚本语言,无统一入口,一个文件可直接运行或被导入。__name__可模拟程序入口,区分主执行代码和被调用文件,还介绍了__file__表示当前文件路径、__doc__表示当前文件描述。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序入口

对于很多编程语言来说,程序都必须要有一个入口,比如 C,C++,以及完全面向对象的编程语言 Java,C# 等。如果你接触过这些语言,对于程序入口这个概念应该很好理解,C 和 C++ 都需要有一个 main 函数来作为程序的入口,也就是程序的运行会从 main 函数开始。同样,Java 和 C# 必须要有一个包含 Main 方法的主类来作为程序入口。

而 Python 则有不同,它属于脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口。

一个 Python 源码文件除了可以被直接运行外,还可以作为模块(也就是库)被导入。不管是导入还是直接运行,最顶层的代码都会被运行(Python 用缩进来区分代码层次)。而实际上在导入的时候,有一部分代码我们是不希望被运行的。

举一个例子来说明一下,假设我们有一个const.py文件,内容如下:

PI = 3.14

def main():
    print ("PI:", PI)

mian()

我们在这个文件里边定义了一些常量,然后又写了一个 main 函数来输出定义的常量,最后运行 main 函数就相当于对定义做一遍人工检查,看看值设置的都对不对。然后我们直接执行该文件(python const.py),输出:

PI: 3.14

现在,我们有一个area.py 文件,用于计算圆的面积,该文件里边需要用到 const.py 文件中的 PI 变量,那么我们从 const.py 中把 PI 变量导入到 area.py 中:

from const import PI

def calc_round_area(radius):
    return PI * (radius ** 2)

def main():
    print ("round area: ", calc_round_area(2))

main()
#输出:
#PI: 3.14
#round area:  12.56

可以看到,const 中的 main 函数也被运行了,实际上我们是不希望它被运行,提供 main 也只是为了对常量定义进行下测试。这时,if __name__ == '__main__'就派上了用场。把 const.py 改一下:

PI = 3.14

def main():
    print ("PI:", PI)

if __name__ == "__main__":
    main()

然后再运行 area.py,输出如下:

round area:  12.56

再运行下 const.py,输出如下:

PI: 3.14

这才是我们想要的效果。

if __name__ == '__main__'就相当于是 Python 模拟的程序入口。Python 本身并没有规定这么写,这只是一种编码习惯。由于模块之间相互引用,不同模块可能都有这样的定义,而入口程序只能有一个。到底哪个入口程序被选中,这取决于 __name__的值。

__name__

__name__是内置变量,用于表示当前模块的名字,同时还能反映一个包的结构。来举个例子,假设有如下一个包:

a
├── b
│   ├── c.py
│   └── __init__.py
└── __init__.py

目录中所有 py 文件的内容都为:

print __name__

我们执行python -c "import a.b.c",输出结果:

a
a.b
a.b.c

由此可见,__name__ 可以清晰的反映一个模块在包中的层次。其实,所谓模块名就是 import 时需要用到的名字,例如:

import tornado
import tornado.web

这里的 tornado 和 tornado.web 就被称为模块的模块名。

如果一个模块被直接运行,则其没有包结构,其 __name__值为__main__。例如在上例中,我们直接运行 c.py 文件(python a/b/c.py),输出结果如下:

__main__

所以,if __name__ == '__main__'我们简单的理解就是: 如果模块是被直接运行的,则代码块被运行,如果模块是被导入的,则代码块不被运行。

Python使用缩进对齐组织代码的执行,所有没有缩进的代码,都会在载入时自动执行。每个文件(模块)都可以任意写一些没有缩进的代码,并在载入时自动执行。为了区分 主执行代码和被调用文件,Python引入了变量:name

1)当文件是被调用时,__name__的值为模块名;
2)当文件被执行时,__name__的值为 ‘__main__’
基于此特性,为测试驱动开发提供了很好的支持,我们可以在每个模块中写上测试代码,这些测试代码仅当模块被Python直接执行时才会运行,代码和测试完美的结合在一起。

Python中的__name__举例

__name__: 是否为主文件

#hello.py  

def sayHello():
    str='hello'
    print(str)

if __name__=='__main__':
    print(('this is main of module "hello.py"'))
    sayHello()

python作为一种脚本语言,我们用python写的各个module都可以包含以上那么一个类似c中的main函数,只不过python中的这种__main__与c中有一些区别,主要体现在:

1、当单独执行该module时,比如单独执行上面的hello.py程序: python hello.py,则输出

this is main of module "hello.py"
hello

可以理解为f __name__=="__main__":" 这一句与c中的main()函数所表述的是一致的,即作为入口;

2、当该module被其它module 引入使用时,其中的"if __name__=="__main__":"所表示的Block不会被执行,这是因为此时module被其它module引用时,其__name__的值将发生变化,__name__的值将会是module的名字。比如在python shell中import hello后,查看hello.__name__

>>> import hello  
>>> hello.__name__  
'hello'  
>>>   

3、在python中,当一个module作为整体被执行时,moduel.__name__的值是"__main__"
当一个module被其它module引用时,module.__name__将是module自己的名字;
当然一个module被其它module引用时,其本身并不需要一个可执行的入口main了。
在这里插入图片描述

#执行index.py
demo: file.demo
demo: demo
index: __main__

在这里插入图片描述

#执行index.py
demo: file.demo
index: __main__

注意:

  • 单独执行任何一个文件时,输出都是 :__main__
  • 通过文件被导入执行时,输出是: 模块名.文件名
  • 通过文件导入执行时,导入语句根据两个文件是否在一个文件夹(模块)下,有所不同
  • from 模块名 import 文件名 或 from 文件名 import 方法名

__file____doc__的用法

__file__:当前文件路径

__doc__ : 当前文件描述

#index.py
'''
Create on XXXX
@author:HHHH
'''

print(__file__)
print(__doc__)
#打印
F:/CodeFile/Python1/file2/index.py

Create on XXXX
@author:HHHH

参考:https://blog.csdn.net/mingyuli/article/details/80956951
http://blog.konghy.cn/2017/04/24/python-entry-program/

Python中,if __name__ == '__main__'是一个常见的用法,用于判断一个.py文件是直接被运行还是被作为模块导入。当一个.py文件直接被运行时,__name__会被设置为'__main__';当一个.py文件被导入为模块时,__name__会被设置为模块的名称。这种用法可以让我们在一个.py文件中同时编写可直接运行的代码和作为模块导入的代码。引用 举个例子,假设我们有两个文件,file_one.py和file_two.py。在file_one.py中,我们可以使用if __name__ == '__main__'来指定某些代码只在该文件被直接运行时执行,而不会在被导入为模块时执行。在file_two.py中,我们可以通过导入file_one模块来使用其中的功能,而不会执行被if __name__ == '__main__'包裹的代码。引用 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Pythonif __name__ == ‘__main__‘用法及原理解析](https://blog.csdn.net/DALEONE/article/details/122267822)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Python 中的 if __name__ == __main__](https://blog.csdn.net/qq_36296794/article/details/126823413)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值