一. 什么是模块?
模块是一组相关功能的集合体,一个模块其实就是一个py文件,
python中的一个功能就是一个函数.
例如:mymodule.py 文件名为 mymodule.py 模块名为 mymodule
模块也分为四类:
1,自定义模块
创建一个py文件.把一堆函数写进去就是一个模块.
2.c语言编写并连接到python解释器的内置模块
time模块. time.sleep()功能 等.
内置的模块能不能满足你所有的需求? 不可能. 所以你必然会自己定义模块
这时候就会出现这样一个情况 对于同样一个功能 你需要自定义 我也自定义. 大家都自定义.这时候就有
人跳出来. 说我写了一个最牛逼的,然后放到网上你们需要了自己下载使用. 这样的我们称之为第三方模块
他其实也属于自定义模块.
3.编译为DLL的c c++扩展
不需要知道什么意思.会用就行
4.一些模块组成的文件夹,成为包.
无论是什么类别的模块使用方法是一样的.
这其中内置与第三方的只要知道如何使用就行了.不需要知道怎么来的.
二. 为什么使用模块.
好处在哪里?
1.减少编写重复代码.很多有现成的代码.直接拿来使用
low么? no我们编写程序是为了创造价值,而不是作无意义的重复劳动
2.从文件界别组织代码. 使我们的代码更加清晰
三. 自定义模块
我们已经知道一个py文件就是一个模块.所以自定义模块非常简单.
案例:
创建一个模块,为其创建几个功能.另外我们可以在模块中
添加普通的py代码.我们也会被执行
文件:spam.py
print('from the spam.py')
money = 100
def func1():
print('func1')
def func2():
print('func2')
但是你想想,模块中应该执行代码么?
不应该 模块是一个工具箱,提供功能才是工具箱该做的事情
四.使用模块
使用关键字来导入模块
import 模块名
文件:模块的使用.py
import spam.py
现在我们有两个文件
模块的使用.py 和 spam.py
模块的使用.py 此时作为执行文件
spam.py此时作为被导入的模块
执行模块的使用.py
我们可以看到输出了
'from the spam,py'
四.1 在我们执行import spam 时到底发生了什么?
很显然执行了spam.py
我们之前说过一旦执行一个py文件 会产生一个该文件的全局命名空间
然后将这个文件中的名称和值得对应关系都放到空间中
总结 : 在执行import时, 做了三件事情
1.创建一个命名空间
2.执行导入的py文件,将产生的名称放入名称空间
3.在执行文件中产生一个姓的名称, 该名称指向被导入文件的命名空间
简单的说其实就是得到了一个名称.这个名字指向被导入文件
一旦有了这个名称,我们就可以通过这个名称找到对应的命名空间中的所有名称
测试:
执行:spam.func1()
输出:'func1'
执行:print(spam.money)
输出:1000
我们成功的访问到了spam模块中的内容
思考:
在模块的使用.py文件中加入:
import spam
import spam
import spam
import spam
问:'from the spam'输出了几次?
答: 一次, 模块中的代码仅在首次导入时执行一次
四.2 执行文件与被导入文件的命名空间相互独立
在spam.py文件中加入
def func3():
print(money)
在模块的使用.py中加入
money = 10000
spam.func()
输出结果为:100
结论: 模块中代码的执行始终以当前文件的命名空间为准
四.3 import 语句的其他写法
1. 取别名:
语法. import xxx as xx
作用: 简化书写
2.导入多个模块:
语法: import spam,mysql,oracle
作用: 简化书写
3.导入模块中名字到当前文件的命名空间
语法: from xxx import xxx,xxx...
作用: 简化书写 今后在使用名字时 不需要再加前缀. 直接使用即可
除了书写方式不同 其他特性完全一致
注意: 可能与当前名称空间中的名称冲突
如果冲突则按照就近查找的原则
4. from 取别名
from xxx import xxx as x
5.from 导入多个
from xx import xxx,xx
6.导入所有
from xx import *
注意: 该方式会导入模块中所有的命名空间到当前命名空间
如果模块中名称非常多的话,极易产生名称冲突 使用的时候要小心
延伸:
模块中可以控制 * 能被导入的名字
在模块文件中加入
__all__=['名字1','名字2']
注意值是字符串类型
五.python文件的两种执行方式
1.作为可执行文件
2.作为模块被导入
作为模块开发者经常需要对自己的功能进行测试
但是这些测试代码在模块被使用者导入的时候不应该执行
这时我们可以使用一个__name__来判断当前文件是作为执行文件还是模块导入
测试:
spam.py模块中加入
print(__name__)
运行模块文件
输入:'__main__'
在模块的使用.py文件中导入spam
运行模块的使用.py
输出:'spam'
总结: 作为执行文件运行时__name__的值为__main__
作为模块被导入时__name__的值为模块名
于是我们可以用一下代码来判断运行状态
if __name__ == '__main__':
print('作为执行文件巡行了!')
else:
print('作为模块导入了!')
六. 模块的搜索路径(重点)
回顾 导入模块时发生了什么?
执行了导入的py文件
要执行必然要先找到这个文件 那到底从哪里去找这个文件呢?
我们之前之所以能够找到是因为你刚好把你要导入的文件和执行文件放一起了
查找的顺序:
内存中已加载的模块->> 内置模块->>sys.path中的模块
创建新文件 模块搜索路径.py
模块搜索路径.py
import sys
print(sys.pash)
详解:
其中项目目录其实是不存在的.这里是因为pycharm自己给加上的.但是我们的执行环境不可能只是
pycharm
所以在开发时要当他不存在
注意:
不要将自己的模块名称和内置的或第三方的冲突
对于内存 和 内置的路径. 我们无法进行操作
唯一 一个可以操作的就是sys.path
结论:
在我们今后的项目开发中 如果需要的模块不在执行文件目录中. 需要手动加入到sys.path以确保程
序可以正确执行
写法:
import sys
sys,path.append('你的模块路径')