模块是一个包含所有自己定义的函数和变量的文件,其后缀名是.py
。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 Python 标准库的方法。知识来源于[1]
容器 -> 数据的封装
函数 -> 语句的封装
类 -> 方法和属性的封装
模块 -> 程序文件
内置命名空间(Built-in Namespaces):Python 运行起来,它们就存在了。内置函数的命名空间都属于内置命名空间,所以,我们可以在任何程序中直接运行它们,比如id()
,不需要做什么操作,拿过来就直接使用了。
全局命名空间(Module:Global Namespaces):每个模块创建它自己所拥有的全局命名空间,不同模块的全局命名空间彼此独立,不同模块中相同名称的命名空间,也会因为模块的不同而不相互干扰。
本地命名空间(Function & Class:Local Namespaces):模块中有函数或者类,每个函数或者类所定义的命名空间就是本地命名空间。如果函数返回了结果或者抛出异常,则本地命名空间也结束了。
程序在查询上述三种命名空间的时候,就按照从里到外的顺序,即:Local Namespaces --> Global Namesspaces --> Built-in Namesspaces
第一种:import 模块名
第二种:from 模块名 import 函数名 或者 from 模块名 import *(浪费所以不推荐)
第三种:import 模块名 as 新名字
if __name__ == '__main__'
Python 则不同,它属于脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口
if __name__ == '__main__'
的意思是:当 .py
文件被直接运行时,if __name__ == '__main__'
之下的代码块将被运行;当 .py
文件以模块形式被导入时,if __name__ == '__main__'
之下的代码块不被运行。
关于__name__ == "__main__"
的知识补充,来源于[2][3][4]
首先建立两个.py
文件,前者是const.py
,后者是area.py
,对__name__ == "__main__"
进行试验
PI = 3.14
def main():
print("PI:", PI)
main()
# PI: 3.14
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
import PI
吗?为什么会把之前的main
也引入????可以看到在两个.py
中都设置了main
函数,然后在第二个.py
文件中先是引入了const
包,再调用main
的时候,把两个main
都调用了
此刻修改前一个.py
文件,加入if __name__ == "__main__":
# PI = 3.14
# def main():
# print("PI:", PI)
# main()
# PI: 3.14
PI = 3.14
def main():
print("PI:", PI)
if __name__ == "__main__":
main()
# PI: 3.14
在加入if __name__ == "__main__":
后运行const.py
得到了原来一样的结果,说明if __name__ == "__main__":
是True
然后运行area.py
,发现也不再调用const.py
的main
了
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
# 第二次
# round area: 12.56
所以if __name__ == "__main__":
是False
所以才有了下面的这句话:__name__
是内置变量,可用于表示当前模块的名字。
import const
print(__name__)
# __main__
print(const.__name__)
# const
当在area.py
中运行print(__name__)
,为__main__
,也解释了之前的if __name__ == "__main__":
是True
。
在area.py
中,__name__
是__main__
是area
在area.py
中,打const.__name__
是const
如果一个 .py
文件(模块)被直接运行时,其__name__
值为__main__
,即模块名为__main__
下面再进行一个小实验,建立一个module.py
,验证上面所说的在area.py
中,__name__
是__main__
是area
def main():
print "we are in %s"%__name__
if __name__ == '__main__':
main()
# we are in __main__
如果是导入,这个和上面的print(const.__name__)
类似
from module import main
main()
# we are in module
综上所述:
(1)“Make a script both importable and executable”
让你写的脚本模块既可以导入到别的模块中用,另外该模块自己也可执行。
(2)if __name__ == '__main__'
的意思是:当 .py
文件被直接运行时,if __name__ == '__main__'
之下的代码块将被运行;当 .py
文件以模块形式被导入时,if __name__ == '__main__'
之下的代码块不被运行。
(3)__name__:
是内置变量,可用于表示当前模块的名字。在自己的模块中,__name__
是 __main__
是模块名字,print(__name__)
是显示__main__
,而在别的.py
中引入const
模块,是print(const.__name__)
是显示const
(4)也就是说if __name__ == '__main__'
,当 .py
文件被直接运行时为真,缩进代码块将被运行;当 .py
文件以模块形式被导入时不为真,缩进代码块不被运行。
__name__:
是内置变量,可用于表示当前模块的名字。在自己的模块中,print(__name__)
是显示__main__
,而在别的.py
中引入再print(别的模块的名字.__name__)
是显示别的模块的名字
。注意结合(5)进行思考。
(5)之后我想了想,如果在第一个.py
中不写上main
,也就是
PI = 3.14
def main():
print("PI:", PI)
运行后是什么都没有的
接着在第二个.py
中run
from const import PI
def calc_round_area(radius):
return PI * (radius ** 2)
def main():
print("round area: ", calc_round_area(2))
main()
# round area: 12.56
也就是如果说在第一个.py
中不输入,在第二个的.py
是没有效果的。
当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入
包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。
创建包分为三个步骤:
(1)创建一个文件夹,用于存放相关的模块,文件夹的名字即包的名字。
(2)在文件夹中创建一个 __init__.py
的模块文件,内容可以为空。
(3)将相关的模块放入文件夹中。
在导入一个包的时候,Python 会根据 sys.path
中的目录来寻找这个包中包含的子目录。
目录只有包含一个叫做 __init__.py
的文件才会被认作是一个包,最简单的情况,放一个空的 __init__.py
就可以了。
[1]https://github.com/datawhalechina/team-learning-program/blob/master/PythonLanguage/15.%20%E6%A8%A1%E5%9D%97.md
[2]https://www.cnblogs.com/alan-babyblog/p/5147770.html
[3]https://www.jianshu.com/p/4b31e860287a
[4]https://blog.csdn.net/anshuai_aw1/article/details/82344884#1%20if%20__name__%20%3D%3D%20’%20rel=