模块

    今日内容

  • 模块简介
  • 导入模块的两种方式
  • 两种导入的优缺点
  • 循环导入问题
  • 判断文件的类型
  • 模块的查找顺序

模块的简介

1.模块

我们可以把模块可以理解为是一系列功能的集合体

  我们调用模块就可以使用集合体中得所有功能

  ps:使用模块编程就是站在巨人的肩膀上

2.模块的分类

  1.内置模块

    解释器自带的,直接可以使用的模块

    就比如我们之前使用过的time模块 

import time
    print(time.time())

# 调用time模块, 我们就可以使用time模块中所有的功能

  2.自定义模块

    需要自己编写

    比如我们之前编写号的注册和登入功能

    我们可以在其他py文件调用这个注册和登入功能了

  3.第三方模块

    就是一些大佬编写好的模块然后放到网上给其他人用

    使用的时候我们需要提前下载才能能使用

    python之所以牛掰就是因为支持python的模块非常的多 非常的全 非常的好用

  所以我们以后拿到一个项目的时候我不着急编写先想想看有没有相应的模块可以实现功能需求

3.模块的表现形式

  1.py文件(一个py文件可以看成是一个模块)

  2.含有多个py文件的文件夹(按照模块功能不同的划分不同的文件夹存储)

  3.已被编译为共享库或DLL的c或C++扩展

  4.使用C编写并链接到python解释器的内置模块

导入模块的两种方式

注意:

  以后项目中的所有py文件的名称都是英文 没有所谓的中文与编号(毕竟python解释器是老外发明的嘛 理解理解)

    如果出现中文与编号 那么我们想要导入这个py文件下的功能时就会导入不了

    命名一定要是英文

    eg:

      01 模块.py (错误的)

      text01.py (正确的)

  py文件在被当做模块导入时不需要考虑后缀

第一种导入方式

1.语法结构:

import 模块名

就比如现在我在pycharm中创建了两个py文件

一个叫 md.py 一个叫 start.py

# 现在在md.py中有一下功能
print('我是来自md.py文件中')
name = 'tony'


def func():
    print('from md.py func')


def func1():
    print(name)


def func2():
    global name
    name = 'kevin'

我们就可以在start.py文件中导入md.py文件

# 现在在start.py中
import md
print(md.name)  # tony
md.func()
'''
from md.py func
tony
'''
md.func1()
'''
form md.py func1
from md.py func
tony

'''
name = 'jason'
md.func2()
print(name)  # jason 名字是不会被修改的 因为md中func2修改name的名字修改的是md名称空间中的name
print(md.name)  # kevin 改变的是md中的name

 

 

 主意:在同一个执行文件中反复的导入同一个模块 导入语句只会执行一次

import md  # 正常导入
import md  # 无效导入
import md  # 无效导入

第二种导入方式

1.语法结构

from ...  import ....

这种导入方式可以直接使用模块中某个功能

现在还是按照上面两个文件演示:

# 在start文件中
from md import name
# 这就可以使用md模块中的name
print(name)  # tony
name = 'jason'
print(name)
'''
直接结果为:jason  
这个时候机会直接改变name的数据值
因为现在这个时候会在start产生一个name然后指向md.py中的name内存地址
但我们重新赋值时就会让原先的name解除绑定然后在与'jason'绑定
'''
print(func)  # 报错 现在这个时候start中就不会有func的mz
print(md.func())  # 报错 这个时候就不能使用md.的形式调用

1.创建执行文件的名称空间

2.创建杯被导入文件的名称空间

3.执行被导入的文件的代码, 并把产生的所有名字都存到被导入的名称空间当中

4.在执行文件中获取指定的名字 指向被导入文件的名称空间

 

两种导入的优缺点

import的导入

1.优点:

  可以通过md点的方式使用到模块中所有的名字并且不会冲突

2.缺点:

  什么都可以导入,但是有时候作者并不想把所有的功能都给你使用

form...import...

1.优点

  可以准确的找到我们需要使用的功能 不需要加模块名前缀

2.缺点

  名字会与执行文件冲突(绑定关系容易被修改)

模块名字的主要事项

# 1.起别名
# 1.有时候会有多个作者起的名字会一样而我们有时候都想用到的时候我们就可以把其中的名字给修改掉即可
from md import name as md_name
from md1 import name as md1_name
# 我们可以通过关键字as把我们是需要的名字给修改掉
# 2.原有的模块名太复杂或太长
import user_interface as user
# 我们也是通过as修改

# 2.导入多个模块名
import os,json,sys
# 上述导入方式尽量导入的时候模块功能相似的时候才这样写 如果不是尽量分开写
import os
import json
import sys
# 尽量这样写

from md import name, func,func1,func2
# 上述导入方式推荐使用 因为多个名字都是来自同一个模块 功能相似
# 名字与名字之间逗号隔开

# 3.全导入
# 需求:需要使用模块名称空间中多个名字,必须是from...import...导入
from md import *
'''
我们可以使用*号顶替
我们就可以在执行文件中使用md中所有的名字
*号还可以控制执行文件导入的数量的多少
我们可以在模块文件中写入__all__=['功能名称'] 控制*能够获取的名字
只有在列表中才能够被调用
'''

循环导入

循环导入就是两个py文件互相导入

循环导入很容易出现报错

  就是需要另一个文件中的名字时很有可能还没有被定义没有准备好被调用, 就会报错

如何解决呢?

  就是在一个文件中需要名字时另一个文件在import上面就先定义好即可

循环导入一定要尽量避免出现 , 如果避免不了就先在导入前定义好名字

文件的判断

当以后我们写项目时,一个项目中的文件会有很多个那么怎么判断它们是哪个文件呢

所有的py文件中都有一个__name_内置名

  当py文件是执行文件的时候__name__的结果是__main__

  当py文件时被导入文件的时候__name__的结果是模块名

__name__主要用于开发模块的作者测试自己的代码使用

  if  __name__  ==  __main__:

    所有功能名字

 只有是执行文件的时候才会执行if语句

 一般只出现在整个文件中的启动文件

 

 

模块名字的查找顺序

1.查找顺序

  1.统一先在内存中查找

  2.然后再内置模块中查找

  3.最后在sys.path中查找(程序系统的环境变量)

2.sys.path

1.导入一个文件 然后在运行过程中删除 发现还可以使用

import md
import time
time.sleep(15)
print(md.name)

'''
当我们运行过程中删除md.py文件是不会报错的因为当我们执行的时候import已经运行过了就会把md文件暂存到了内存中所以还是能够找到md中的名字
但是如果再次运行就会报错了
'''

2.创建一个跟内置模块名相同的名字

import time
print(time.time())  # 会获得一个时间戳
from time import name
print(name)  # 会报错因为time中没有name名字
'''
这个时候我们就可以得知名字的查找顺序是先从内存中找然后在从内置中查找
就算自己编写了一个time.py文件也是先从内置中查找
所以器模块名时尽量不要跟内置模块名冲突
'''

3.sys.path中查找

首先我们要知道导入模块时谁是执行文件

  所有的路径都是参考执行文件来的

import sys
print(sys.path)
'''
[
'D:\\MYpycharm\\day19', 
'D:\\MYpycharm\\day19', 
'D:\\PyCharm 2022.1.2\\plugins\\python\\helpers\\pycharm_display', 
'D:\\python3.6\\python36.zip', 
'D:\\python3.6\\DLLs', 
'D:\\python3.6\\lib', 
'D:\\python3.6', 
'D:\\python3.6\\lib\\site-packages', 
'D:\\PyCharm 2022.1.2\\plugins\\python\\helpers\\pycharm_matplotlib_backend'
]
我们会发现sys.path中的所有路径都是在一个列表中的
只要模块名的路径在里面那么我们就可以调用这个模块
'''

如果想要调用的模块内存中没有内置模块也没有那么我们可以先把模块名的绝对路径添加到sys.path中就行了

因为sys.path中是一个列表所以我们只要在列表末尾添加即可

sys.path.append(模块名的路径)

# 在start文件同级别中创建一个xxx文件夹,该文件夹中有add.py文件

name = 'jason'
# 在start文件中
import sys
# 添加不同级别的py文件
sys.path.append(r'D:\MYpycharm\day19\xxx') # py文件不需要添加
import add  # 虽然add会飘红但是不影响程序运行
print(add.name)  # jason

还有from...import...也可以从文件夹中导入模块名

from xxx import add
print(add.name)  # jason
# 这个时候就不需要添加sys.path路径中了

如果文件夹下还有文件夹我也可以添加

from xxx.aaa.bbb.user import name
print(name)  # tony
# 可以在文件夹后面是有点继续添加文件夹

 

  

 

 

 

 

 

 

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

print(name)  # jason 名字是不会被修改的 因为mdfunc2修改name的名字修改的是md名称空间中的name
print(md.name) # kevin 改变的是md中的name
posted @ 2022-07-13 18:54  stephen_hao  阅读(90)  评论(0编辑  收藏  举报