模块句式
模块简介
"""
python屈辱史
python刚开始出来的时候被其他编程程序员瞧不起
ps:太简单 写代码都是调用模块(调包侠 贬义词)
随着业务的扩展其他程序员也需要使用python写代码
写完之后发现python真香 贼好用(调包侠 褒义词)
为什么python很牛逼
python之所以牛逼就是因为支持python的模块非常的多 非常的全 非常的猛
作为一名python程序员
将来接收到某个业务需求的时候 不要上来就想着自己写 先看看有没有相应的模块已经实现
"""
1.如何理解模块
模块可以看成是一系列功能的结合体
使用模块就相当于拥有了这结合体内的所有功能
ps:使用模块编程就相当于站在巨人的肩膀上
2.模块的分类
1.内置模块
解释器自带的 直接就可以使用的模块
eg:
import time
time.sleep(3)
2.自定义模块
自己写的模块
eg:
注册功能 登录功能
3.第三方模块
别人写的模块 存在于网络上 使用之前需要提前下载
eg:
图形识别 图形可视化 语音识别
3.模块的表现形式
1.py文件(py文件也可以称之为是模块文件)
2.含有多个py文件的文件夹(按照模块功能的不同划分不同的文件夹存储)
3.已被编译为共享库或DLL的c或C++扩展(了解)
4.使用C编写并链接到python解释器的内置模块(了解)
导入模块的两种句式
"""
补充说明
以后真正的项目中 所有的py文件名称都是英文
没有所谓的编号和中文
eg:
错误的 01.变量的使用
正确的 test01.py
学习模块的时候 模块文件的名称就得用英文
py文件被当做模块导入的时候不需要考虑后缀
"""
1.导入模块的句式1 import句式
import md
# 导入一个模块文件就会执行这个文件
"""
import md
执行文件是 02 模块的导入句式.py
被导入文件是 md.py
1.会产生执行文件的名称空间
2.产生被导入文件的名称空间并运行该文件内所有的代码 存储名字
3.在执行文件中会获取一个模块的名字 通过该名字点的方式就可以使用到被导入文件名称空间中的名字
补充说明
同一个程序反复导入相同的模块 导入语句只会执行一次
import md 有效
import md 无效
import md 无效
"""
# money = 10
# print(md.money)
# print(money)
# def read1():
# print('我是执行文件里面的read函数')
# md.read2()
# money = 1000
# md.change()
# print(money)
# print(md.money)
2.导入模块的句式2 from...import...句式
# from md import money # 指名道姓的导入
# print(money) # 999
# money = '嘿嘿嘿'
# print(money) # 嘿嘿嘿
# print(read1)
# print(md.read1())
from md import money, read1
read1()
"""
1.创建执行文件的名称空间
2.创建被导入文件的名称空间
3.执行被导入文件中的代码 将产生的名字存储到被导入文件的名称空间中
4.在执行文件中获取到指定的名字 指向被导入文件的名称空间
"""
导入模块文件底层发生的事情

两种导入句式的优缺点
import md
优点:通过md点的方式可以使用到模块内所有的名字 并且不会冲突
缺点:md什么都可以点 有时候并不想让所有的名字都能被使用
from md import money, read1
优点:指名道姓的使用指定的名字 并且不需要加模块名前缀
缺点:名字及其容易产生冲突(绑定关系被修改)
补充知识
1.起别名
情况1:多个模块文件名相同(多个人写文件就可能会发生冲突)
from md import money as md_my
from md1 import money as md1_my
print(md_my)
print(md1_my)
情况2:原有的模块文件名复杂
import mdddddddddd as md
from mdddddd import money as my
2.导入多个名字
import time, sys, os
上述导入方式建议多个模块功能相似才能适应 不相似尽量分开导入
import time
import os
import sys
from md import money, read1, read2
上述导入方式是推荐使用的 因为多个名字出自于一个模块文件
3.全导入
需求:需要使用模块名称空间中很多名字 并且只能使用from...import句式
from md import * # *表示所有
使用的时候就不需要md点的形式了,可以直接使用
eg:
print(money)
read1()
change()
ps:针对*号的导入还可以控制名字的数量,也就是被导入模块文件对执行文件的控制限制
在被导入模块文件中可以使用__all__ = [字符串的名字]控制*能够获取的名字
eg:
__all__ = ['money']
这样写,执行文件如果想import * ,那么它只能拿到money
循环导入问题
1.如何理解循环导入
循环导入就是两个文件彼此导彼此
2.循环导入容易出现报错现象
使用彼此的名字可能是在没有准备好的情况下就使用了
3.如何解决循环导入报错现象
彼此在使用彼此名字之前 先准备好
"""循环导入将来尽量避免出现!!! 如果真的避免不了 就想办法让所有的名字在使用之前提前准备好"""
判断文件类型(脚本文件)
学习完模块之后 以后我们的程序运行起来可能涉及到的文件就不止一个
所有的py文件中都自带一个__name__内置名
当py文件是执行文件的时候 __name__的结果是__main__
当py文件是被导入文件的时候 __name__的结果是模块名(文件名)
__name__主要用于开发模块的作者测试自己的代码使用
if __name__ == '__main__':
当文件是执行文件的时候才会执行if的子代码
## 只有在当前文件下打印__name__的结果是__main__,如果被别人导入这个模块文件,在对方那个执行文件的__name__打印出来的是模块文件的名字而不是__main__
上述判断一般只出现整个程序的启动文件中,只有启动文件才会有if __name__ == '__main__':
ps:在pycharm中可以直接编写main按tab键自动补全
模块的查找顺序
"""
1.先去内存中查找
2.再去内置中查找
3.再去sys.path中查找(程序系统环境变量) 下面详细的讲解
"""
验证先去内存中查找
1.导入一个文件 然后在导入过程中删除该文件 发现还可以使用
import md
import time
time.sleep(15)
print(md.money)
## 是因为我们删除的是硬盘上的程序,他还能打印出来是因为在内存上还有这份数据,如果重启程序肯定就会报错了
验证再去内置中查找
2.创建一个跟内置模块名相同的文件名
# import time
# print(time.time())
from time import name
print(name)
ps:创建模块文件的时候尽量不要与内置模块名冲突
3.导入模块的时候一定要知道谁是执行文件
所有的路径都是参照执行文件来的
import sys
sys.path.append(r'D:\pythonProject\day22\xxx')
import mdd
print(mdd.name)
谁是执行文件,就把谁当前所在的路径为标准
"""
1.通用的方式
sys.path.append(目标文件所在的路径)
2.利用from...import句式
起始位置一定是执行文件所在的路径
from xxx import mdd
"""
绝对导入与相对导入
"""
##############################################
只要涉及到模块的导入 那么sys.path永远以执行文件为准
##############################################
"""
绝对导入
其实就是以执行文件所在的sys.path为起始路径 往下一层层查找
from ccc import b
from ccc.ddd.eee import b
ps:由于pycharm会自动将项目根目录添加到sys.path中所以查找模块肯定不报错的方法就是永远从根路径往下一层层找
如果不是用pycharm运行 则需要将项目跟目录添加到sys.path(针对项目根目录的绝对路径有模块可以帮助我们获取>>>:os模块)
相对导入
储备知识
.在路径中意思是当前路径
..在路径中意思是上一层路径
../..在路径中意思是上上一层路径
相对导入可以不参考执行文件所在的路径 直接以当前模块文件路径为准
1.只能在模块文件中使用 不能在执行文件中使用
2.相对导入在项目比较复杂的情况下 可能会出错
ps:相对导入尽量少用 推荐使用绝对导入
包的概念
1.如何理解包
专业的角度:内部含有__init__.py的文件夹
直观的角度:就是一个文件夹
2.包的作用
内部存放多个py文件(模块文件) 仅仅是为了更加方便的管理模块文件
3.具体使用
import 包名
导入包名其实导入的是里面的__init__.py文件(该文件里面有什么你才能用什么),如果什么都没有就是个空的py文件,如果我想要使用包下的其他的py文件,就可以把其他模块文件都导入__init__py文件中,他有一点像我们的__all__方法,想要谁被使用就加进来
eg:
from . import md1
from . import md2
from . import md3
其实也可以跨过__init__.py直接导入包里面的模块文件
"""
针对python3解释器 其实文件夹里面有没有__init__.py已经无所谓了 都是包
但是针对Python2解释器 文件夹下面必须要有__init__.py才能被当做包,才能被导入使用
很多包内部都有__init__是为了兼容python2和3
"""
编程思想的转变
1.小白阶段
按照需求从上往下堆叠代码(面条版) 单文件
2.函数阶段
将代码按照功能的不同封装成不同的函数 单文件
3.模块阶段
根据功能的不同拆分不同的模块文件 多文件
"""
小白阶段相当于将所有的文件全部存储在C盘并且不分类
函数阶段相当于将所有的文件在C盘下分类存储
模块阶段相当于将所有的文件按照功能的不同分门别类到不同的盘中
目的为了更加方便快捷高效的管理资源
"""
软件开发目录规范
针对上述的第三个阶段 分模块文件多了之后还需要有文件夹
我们所使用的所有的程序目录都有一定的规范(有多个文件夹)
1.bin文件夹
用于存储程序的启动文件 start.py
2.conf文件夹
用于存储程序的配置文件 settings.py
3.core文件夹
用于存储程序的核心逻辑 src.py
4.lib文件夹
用于存储程序的公共功能 common.py
5.db文件夹
用于存储程序的数据文件 userinfo.txt
6.log文件夹
用于存储程序的日志文件 log.log
7.interface文件夹
用于存储程序的接口文件 user.py order.py goods.py
8.readme文件(文本文件)
用于编写程序的说明、介绍、广告 类似于产品说明书
9.requirements.txt文件
用于存储程序所需的第三方模块名称和版本
"""
我们在编写软件的时候 可以不完全遵循上面的文件名
start.py可以放在bin文件夹下也可以直接放在项目根目录
db文件夹等我们学到真正的项目会被数据库软件替代
log文件夹等我们学到真正的项目会被专门的日志服务替代
"""

浙公网安备 33010602011771号