学习Python-Day21
昨日内容回顾
-
索引取值与迭代取值的差异
-
索引取值
优点:可以重复取出任意的值
缺点:不能取无序容器类型的数据类型
-
迭代取值
优点:取值通用方式
缺点:取值的方向是固定的,从前往后取。
-
-
模块简介
就是具有一系列功能的结合体
-
模块的分类
- 内置模块:解释器自带,直接可以使用的模块
- 自定义模块:自己写的
- 第三方模块:别人写好,下载后可以拿来用的。
-
导入模块的两种句式
1.import 句式 优点:通过前缀点的方式使用到模块内所有的名字,并且不会冲突 缺点:因为什么都可以点,所以有时候不想让所有名字都能使用 2.from...import...句式 优点:指名道姓的使用指定的名字,并且不需要加模块前缀 缺点:名字及其容易冲突(绑定关系被修改) -
导入模块的补充知识
-
起别名
情况1:多个模块文件名一样时可以改新名
情况2:原有模块文件名复杂
-
导入多个名字
import md1, md2, md3建议该导入方式多个模块相似才能适应,不相似尽量分开导入
from md import money, read1, read2建议该导入方式的名字都来自同一个模块文件
-
全导入
from md import *表示所有在
模块文件中可以使用__all__ = [字符串的名字]控制*能够获取的名字
-
-
循环导入问题
-
两个文件相互导彼此,会出现循环导入问题
-
解决问题的方法有两种
1.就是避免发生
2.想准备好要导入的名字,再导入。
-
-
判断文件类型
- py文件都自带一个
__name__内置名 - 当py文件执行文件时,
__name__的结果是__main - 当py文件被导入文件时,
__name__的结果是模块名(文件名)
- py文件都自带一个
-
模块的查找顺序
- 从内存上找
- 从内置那边找
- 从sys.path找(程序系统环境变量)
创建模块文件的时候尽量不要与内置模块名冲突
-
通用方式
sys.path.append(目标文件所在的路径)
-
利用 from...import
起始位置一定是执行文件所在的路径
from xxx import mdfrom xxx.xx.x import md(文件一层层包含其中就用点的方法,一步步找到被导入文件。)
from xxx.xx.x.md import name(也可以用点的方式导入文件具体的名字)
今日学习内容
一、绝对导入与相对导入
只要涉及到模块的导入,那么sys.path永远以执行文件为准
-
绝对导入
其实就是以执行文件所在的sys.path 为起始路径,往下一层层查找
from aaa import md2
from bbb.aaa import md2
'由于pycharm会自动将项目根目录添加到sys.path中所有查找模块肯定不报错的方法就是永远从根路径往下一层层找'
如果不是用pycharm运行,则需要讲项目根目录添加到sys.path(针对项目根目录的绝对值路径有模块可以帮助我们获取>>>:os模块)
os模块是与操作系统交互的一个接口
-
相对导入
? 储备知识
. 在路径中意思是当前路径 ..在路径中意思是上一层路径 ../..在路径中意思上上一层路径 相对导入可以不参考执行文件所在的路径,不能在执行文件中使用 1.只能在模块文件中使用,不能在执行文件中使用 2.相对导入在项目中比较复杂的情况下,可能会出错
二、包的概念
-
如何理解包
专业的角度:内部含有
__init__.py的文件直观的角度:就是一个文件夹
-
包的作用
内部存放多个py文件(模块文件),仅仅是为了更方便的管理模块文件
-
具体使用
import包名导入包名其实导入的是里面的
__init__.py文件(该文件里面有什么就能用什么)。其实也可以跨过
__init__.py直接将其他模块文件导入包里面。
注意:
python2和python3还是有区别的。
针对python3解释器,其实文件夹里面没有___init__.py都可以当做包。
针对python2解释器,文件夹下面必须要有___init__.py才能被当做包。
三、编程思想的转变
-
小白阶段
按照需求从上往下堆叠代码(面条版) 单文件
-
函数阶段
将代码按照功能的不同封装成不同的函数 单文件
-
模块阶段
根据功能的不同拆分不同的模块文件 多文件
注意:
小白阶段相当于将所有文件全部保存到C盘并且不分类
函数阶段相当于将所有的文件在C盘下分类
模块阶段相当于将所有文件按照功能不同分门别类到不同的盘中
目的是为了更加方便快捷高效的管理资源
四、软件开发目录规范
针对上述的第三个阶段,分模块文件多了之后还需要有文件夹
我们所使用的所有的程序目录都有一定的规范。
| 文件夹 | 作用 | 文件 |
|---|---|---|
| bin | 用于存储程序的启动文件 | start.py |
| conf | 用于存储程序的配置文件 | settings.py |
| core | 用于存储程序的核心逻辑 | src.py |
| lib | 用于存储程序的公共资源 | common.py |
| db | 用于存储程序的数据文件 | userinfo.txt |
| log | 用于存储程序的日志文件 | log.log |
| interface | 用于存储程序的接口文件 | user.py |
| readme.txt | 用于编写程序的说明、介绍、广告、类似于产品的说明书 |
| 文件夹 | 作用 | |
|---|---|---|
| requirements.txt | 用于存储程序所需的第三方模块名称和版本 |
注意:
我们在编写软件的时候,可以不完全遵循上面的文件名。
- start.py可以放在bin文件夹下也可以直接放在项目根目录。
- db文件夹等我们学到真正的项目会被数据库软件替代
- log文件夹等我们学到真正的项目会被专门的日志服务替代
五、常见内置模块
-
collections 模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
-
namedtuple:生成可以使用名字来访问元素内容的tuple
'可以表示一个坐标' 1.两个参数 from collections import namedtuple point = namedtuple('二维坐标系', ['x', 'y']) p = point(2, 3) print(p) print(p.x) print(p.y) '运行结果: 二维坐标系(x=2, y=3) 2 3' 2.三个参数 cirle = namedtuple('三维坐标系', 'x y z') c = cirle(2, 3, 4) print(c) print(c.x) print(c.y) print(c.z) '运行结果: 三维坐标系(x=2, y=3, z=4) 2 3 4' 3.扑克对应花色点数 p = namedtuple('扑克牌', ['花色', '点数']) res1 = p('?', 'K') res2 = p('?', 'A') print(res1) print(res2) -
deque:双端队列,高效实现插入和删除操作的双向列表,适合用于队列和栈。
'使用list存数据时,按索引访问元素很快,但是插入和删除元素句很慢。因为list是线性存储,数据量大的时候,插入和删除效率很低' from collections import deque q = deque(['a', 'b', 'c']) q.append('x') q.appendleft('y') print(q) '运行结果: deque(['y', 'a', 'b', 'c', 'x'])' p = deque(['x', 'y', 'z']) p.pop() p.popleft() print(p) '运行结果: deque(['y'])' -
Counter:计时器,主要用来计数
'Counter类的目的是用来跟踪值出现的次数' 1. from collections import Counter a = Counter('xzwybsdzxwxysxdsxdszd') print(a) '运行结果: Counter({'x': 5, 's': 4, 'd': 4, 'z': 3, 'w': 2, 'y': 2, 'b': 1})' '它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为k值,其计数作为v值' 2.for循环 res = 'xzwybsdzxwxysxdsxdszd' new_dict = {} for i in res: if i not in new_dict: new_dict[i] = 1 else: new_dict[i] += 1 print(new_dict) '运行结果: {'x': 5, 'z': 3, 'w': 2, 'y': 2, 'b': 1, 's': 4, 'd': 4}' -
OrderedDict:有序字典
-
'''使用dict时,Key是无序的。在对迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict'''
1.使用python2时候,dict的Key是无序的:
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d
{'a': 1, 'c': 3, 'b': 2}
2.加上OrderedDict后OrderedDict的Key是有序的:
>>> from collections import OrderedDict
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
3.OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:
>>> from collections import OrderedDict
>>> od = OrderedDict()
>>> od['c'] = 1
>>> od['b'] = 2
>>> od['a'] = 3
>>> od.keys()
['c', 'b', 'a']
-
defaultdict:带有默认值的字典
1.当字典里的值不存在时返回keyError是一个默认值,不报错。 from collections import defaultdict d1 = dict() d2 = defaultdict(list) print(d1['a']) #报错 print(d2['a']) #[] 'defaultdict的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值' 2.默认字典: from collections import defaultdict l1 = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90, 100] dict1 = defaultdict(list) for i in l1: if i > 66: dict1['key1'].append(i) elif i < 66: dict1['key2'].append(i) else: continue print(dict1) 3.for 循环 : l1 = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90, 100] key1 = [] key2 = [] dict1 = {'key1': key1, 'key2': key2} for i in l1: if i > 66: key1.append(i) elif i < 66: key2.append(i) else: continue print(dict1)
-
时间模块之time模块
时间的三种格式:
? 1.时间戳 time.time() 机器能识别的时间
? 2.结构化时间 time.gmtime()
? 3.格式化时间 time.strftime() 人能看懂的时间字符串import time 1.时间戳 时间戳表示的是从1970年1月1日00:00:00开始按秒计算到今天的时间 print(time.time()) #返回一串数字 时间戳-->结构化时间 2.本地的时间 print(time.localtime()) '运行结果:time.struct_time(tm_year=2022, tm_mon=7, tm_mday=14, tm_hour=20, tm_min=10, tm_sec=48, tm_wday=3, tm_yday=195, tm_isdst=0)‘ 3.UTC时间,与英国伦敦当地时间一致 print(time.gmtime()) '运行结果:time.struct_time(tm_year=2022, tm_mon=7, tm_mday=14, tm_hour=12, tm_min=11, tm_sec=54, tm_wday=3, tm_yday=195, tm_isdst=0)'' 4.按照某种格式显示的时间(格式化的字符串形式的时间):struct_time print(time.strftime('%Y-%m-%d %H-%M-%S')) #2022-07-14 20-09-13 5.%X可以表示后面的%H-%M-%S print(time.strftime('%Y-%m-%d %X')) #2022-07-14 20:09:13 结构化时间-->时间戳 6.time.mktime(结构化时间) t1 = time.localtime() print(time.mktime(t1))#1657800940.0 结构化时间-->字符串时间 7.time.strftime("格式定义","结构化时间") 人普遍看的时间 t2 = time.strftime("%Y-%m-%d", time.localtime()) print(t2) #2022-07-14 字符串时间-->结构化时间 8.time.strptime(时间字符串,字符串对应格式) t3 = time.strptime("2022-3-15", "%Y-%m-%d") print(t3) '运行结果:time.struct_time(tm_year=2022, tm_mon=3, tm_mday=15, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1)' t4 = time.strptime("07/24/2017", "%m/%d/%Y") print(t4) '运行结果:time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)