「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」。
正式的Python专栏第76篇,同学站住,别错过这个从0开始的文章!
前篇学委分享了一个进程池,里面特别谈到,必须要在’__main__‘代码块内或者内部调用其他模块来创建进程池,否则就会报错。
那么背后是什么原因呢?我认为可以分为两篇文章可以解释的很清楚。
本篇为独立一篇,我们看看__name__这个内置属性。
第一点 脚本/模块内 可执行代码 加载的时候必然被执行
严格来说’__main__‘代码块,并非脚本的入口,因为python程序运行时是从模块顶行开始,逐行进行翻译执行的。所以 可执行代码(表达式或者函数调用等)一旦被解释器加载,立马就执行了,根本不必等到放到’__main__‘代码块内。
这是第一点,也是python编译器的原理。如果需要更多解释,学委后面围绕python编译器运行的源码展再做分享,但不在本文范围中。
第二点 主动加载模块时,模块的__name__属性会被设置为’__main__‘
python解释器在直接运行一整个脚本/模块的时候,设置了__name__这个模块内置属性(内置变量),把它的值设置为’__main__‘。
这里说的‘主动加载’其实是相对的,学委为了解释方便提出的概念,更准确的是,执行运行模块。一个python模块就是代码集合,它本身没有能动性的,这个读者们必须搞清楚。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/2/27 10:53 下午
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat: 雷学委
# @XueWeiTag: CodingDemo
# @File : lib01.py
# @Project : DeepDivePython
def demo():
print("demo in lib:", __name__)
print("leixuewei")
demo()
if __name__ == "__main__":
print("execute in main block")
复制代码
如下图所示,我们看到使用:venv/bin/python <lib01.py\的路径>,这个本质上是用编译器运行python脚本。
这里模块lib01._name_属性的值变成了’__main__‘,最后打印了‘execute in main block’。
第三点 模块被动加载时,内置属性__name__属性的值变成模块名
我们在import一个模块的时候,除了’__main__‘代码块内的代码是不会被运行的,其他模块内如果出现可执行的代码,则无碍,它们照常继续被加载执行。
如下面代码所示
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/2/27 10:55 下午
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat: 雷学委
# @XueWeiTag: CodingDemo
# @File : call_lib01.py
# @Project : DeepDivePython
import lib01
lib01.demo()
复制代码
如下图所示,这里打印了三句,前两句是加载lib01的过程中一边解释执行的输出。
第三句子为:call_lib01.py的lib01.demo()调用的输出结果。
因为lib01的内置属性__name__属性的值变成了’lib01‘了。
也就是前面学委分享的大多数demo代码都是直接在脚本内调用方法执行的。
结语
本文就分享3点,希望读者都能理解,吃透!这个是python编程的基础。
喜欢Python的朋友,请关注学委的 Python基础专栏 or Python入门到精通大专栏
持续学习持续开发,我是雷学委!
编程很有趣,关键是把技术搞透彻讲明白。
欢迎关注微信,点赞支持收藏!