模块

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找不到,报错;

 

  

原文地址:https://www.cnblogs.com/0627zhou/p/9425966.html