模块
1.模块的分类
内置模块:安装在Python解释器的时候跟着装上的那些方法
自定义模块:你写的功能
第三方模块/扩展模块:没在Python解释器安装时的方法,一般放在 Lib/site-packages
2.什么是模块
a:有的功能开发者自己无法完成,这样需要借助已经实现的函数/类完成功能
b:Python解释器无法直接和操作系统交互,只能借助c语言,所以要导入;
c:扩展模块一般放在硬盘中,只有你要用的时候,会将它导入到内存中
d:好处 分类管理方法 节省内存 提供更多功能
3.怎样使用模块
a:自定义模块时,只能创建.py文件才能导入, 导入语句 import 模块名(不加.py,也要满足变量的命名规范)
b:import这个模块相当于执行了这个模块所在的py文件,而且一个模块重复导入时,不会被重复执行;
c:在导入模块时发生的步骤
所以在导入的模块在使用变量时一定找的是自己命名空间中的变量,这是一个单向的通道,被导入的模块不能往回找
d:导入多个模块时,要分行导入,遵循pep8规范
3.from 模块名 import 变量名 <==> import 模块名
a:模块导入时,会将模块从头至尾执行一遍
main.py from my_module import login login() #输出结果: 导入我的时候,会从上到下读完,我被重新赋值了 wuser my_module.py name = 'alex' def login(): print('导入我的时候,会从上到下读完,我被重新赋值了',name) name = 'wuser'
b:from import重复导入模块时,虽然空间只会被执行一次,但import引用会发生改变
mian.py from my_module import login def login(): print('在下面的语句执行时,我的引用又发生了改变') login() #这时引用的自己的命名空间 from my_module import login login() #import使引用又发生了改变 #输出结果: alex 在下面的语句执行时,我的引用又发生了改变 导入我的时候,会从上到下读完,我被重新赋值了 wuser my_module.py name = 'alex' print(name) def login(): print('导入我的时候,会从上到下读完,我被重新赋值了',name) name = 'wuser'
4.模块相关知识
a:把模块当成脚本运行
运行一个py文件的两种方式
1).以模块的形式运行
import my_module
if __name__ == '__main__':
my_module.login()
a:当你执行当前的文件时,print(__name__)的值为__main__
而当你作为模块导入的时候,你的__name__就是你的文件名
b:所以在编写文件时,所有不在函数和类中封装的内容都应该写在if __name__ == '__main__':语句中
2).直接pycharm运行 cmd运行
----以脚本的形式运行
那么需要在本文件中直接打印的代码上加上
if __name__ == '__main__':
b:当模块遇见反射:
#单独运行模块文件second.py时 import sys file = sys.modules['__main__'] print(sys.modules['__main__']) #<module '__main__' from 'D:/solor/练习/second.py'> def func(): print('我被执行了') getattr(file,'func',True)() #输出结果 <module '__main__' from 'D:/solor/练习/second.py'> 我被执行了 # first.py 运行导入模块second.py时 import second 输出结果 <module '__main__' from 'D:/solor/练习/first.py'> TypeError: 'bool' object is not callable
可以看出这里面的sys.modules['__main__']得到的空间地址发生了改变;
解决方法:
#执行模块second.py import sys file = sys.modules[__name__] print(sys.modules[__name__]) #<module '__main__' from 'D:/solor/练习/second.py'> def func(): print('我被执行了') getattr(file,'func',True)() #输出结果 <module '__main__' from 'D:/solor/练习/second.py'> 我被执行了 #first.py导入模块second.py时 <module 'second' from 'D:\\solor\\练习\\second.py'> 我被执行了
这里将'__main__'改成了__name__就能让你的反射利于不败之地;所以你再反射自己模块内容时,
语法:import sys getattr(sys.modules[__name__],变量名) __name__指的就是本文件空间的名字;
c;小知识:
# import aaa # 模块导入的时候 # python的执行 # 解释 - 编译 # 当一个文件作为一个脚本被导入的时候 # 就会在这个文件所在的目录的__pycache__下生成一个编译好的文件 # 为了之后导入这个文件的时候直接读这个编译好的pyc文件就可以 # 可以节省一些导入时候的时间
d:当程序一直运行过程中,你导入的模块如果发生改变,你的程序会感知不到
import second import time second.func1() time.sleep(20) second.func1() #当你运行时,如果模块second发生改变,程序会感知不到
5.模块的循环引用
执行到第二步时,模块不会被重复导入,所以会执行第三句话,到第四句时,因为第一步只执行了import而没有往下执行
所以funca找不到,报错;