模块学习之绝对导入与相对导入、包的概念、软件开发目录规范、常见内置模块
绝对导入与相对导入
1.绝对路劲与相对路劲
绝对路劲:绝对路径是指文件在硬盘上真正存在的路径,不需要有参考系
相对路劲:需要有参考系
ps:模块导入中,sys.path永远都是以执行文件为准
解决这个这个问题:
1.将aaa添加到sys.path中
2.在模块中导入模块,使用from...import,也称绝对导入,看执行文件在哪然后以执行文件的路劲为起始路径一层一层往下找
2.绝对导入
以执行文件所在的sys.path为起始路劲,然后一层一层向下找
eg:from aaa import b
如果py文件更改了路径pycharm会自动将目录更改
由于pycharm会自动**将当前项目根目录添加到sys.path**中所以查找模块肯定不报错的方法就是永远从根路径往下一层层找
如果不是用pycharm运行就会报错 则需要将项目跟目录添加到sys.path(针对项目根目录的绝对路径有模块可以帮助我们获取--->os模块)
3.相对导入
3.1.储备知识
.在路径中意思是当前路径
..在路径中意思是上一层路径
../..在路径中意思是上上一层路径
3.2.概括
相对导入可以不参考执行文件所在的路径 直接以当前模块文件路径为准
1.只能在模块文件中使用 **不能在执行文件中使用**
2.相对导入在项目比较复杂的情况下 可能会出错
ps:相对导入尽量少用 推荐使用绝对导入
包的概念
1.如何理解包
专业的角度:内部含有双下__init__.py的文件夹
直观的角度:就是一个文件夹
2.包的作用
内部存放多个py文件(模块文件) 仅仅是为了更加方便的管理模块文件
3.包的使用
import 包名
导入包名其实导入的是里面的__init__.py文件(该文件里面有什么你才能用什么)
其实也可以跨过__init__.py直接导入包里面的模块文件
ps:针对python3解释器 其实文件夹里面有没有__init__.py已经无所谓了 都是包
但是针对Python2解释器 文件夹下面必须要有__init__.py才能被当做包
编程思想的转变
1.小白阶段
按照需求从上往下堆叠代码(面条版) 单文件
相当于将所有的文件全部存储在C盘并且不分类
2.函数阶段
将代码按照功能的不同封装成不同的函数 单文件
相当于将所有的文件在C盘下分类存储
3.模块阶段
根据功能的不同拆分不同的模块文件 多文件
相当于将所有的文件按照功能的不同分门别类到不同的盘中
4.目的
目的为了更加方便快捷高效的管理资源,变得更合理,更有规矩,不再是那么的笼统,而是更有计划有模块的划分
软件开发目录规范
根据我们的需求,高效的管理资源,分模块文件多了之后还需要有文件夹
行业规范我们所使用的所有的程序目录都有一定的规范(有多个文件夹)
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
8.readme文件(文本文件)
用于编写程序的说明、介绍、广告 类似于产品说明书
9.requirements.txt文件
用于存储程序所需的第三方模块名称和版本
常见内置模块
1.collections模块
import collections
'''
鼠标移动到collections上按左键
查看一些可用的功能
'''
__all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList',
'UserString', 'Counter', 'OrderedDict', 'ChainMap']
1.1.namedtuple
from collections import namedtuple
# # 初始化方式一:
# Point = namedtuple('坐标', ['x', 'y'])
# print(Point) # <class '__main__.坐标'>
# res1 = Point(1, 3)
# res2 = Point(10, 43)
# print(res1, res2) # 坐标(x=1, y=3) 坐标(x=10, y=43)
# print(res1.x) # 1
Point = namedtuple('坐标', 'x y z')
print(Point) # <class '__main__.坐标'>
res1 = Point(1, 3, 12)
res2 = Point(10, 43, 15)
print(res1, res2) # 坐标(x=1, y=3, z=12) 坐标(x=10, y=43, z=15)
print(res1.x) # 1
1.2.deque
是为了高效实现插入和删除操作的双向列表,适合于队列和栈,也称双端队列
deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
from collections import deque
q = deque()
q.append(111)
q.append(222)
q.append(333)
print(q) # deque([111, 222, 333])
1.3.OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺
OrderedDict的Key会按照插入的顺序排列,不是Key本身排序
order = dict([('a', 1), ('b', 2), ('c', 3)])
print(order) # {'a': 1, 'b': 2, 'c': 3}
1.4.defaultdict
from collections import defaultdict
res = defaultdict(k1=[],k2=[])
print(res) # defaultdict(None, {'k1': [], 'k2': []})
1.5.counter
Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。
res = 'abcdeabcdabcaba' # {'a':2,'b':5 }
# new_dict = {}
# for i in res:
# if i not in new_dict:
# new_dict[i] = 1
# else:
# new_dict[i] += 1
# print(new_dict)
from collections import Counter
res1 = Counter(res)
print(res1)
2.times模块
时间的三种格式
1.时间戳 time.time()
2.结构化时间 time.gmtime()
3.格式化时间 time.strftime()
import time
print(time.time()) # 1657796937.5463662
# 结构化时间
print(time.gmtime()) # time.struct_time(tm_year=2022, tm_mon=7, tm_mday=14, tm_hour=11, tm_min=9, tm_sec=21, tm_wday=3, tm_yday=195, tm_isdst=0)
# 格式化时间
print(time.strftime('%Y-%m-%d %H:%M:%S')) # 2022-07-14 19:10:38
print(time.strftime('%Y-%m-%d %X')) # 2022-07-14 19:11:47
print(time.strptime('2022-07-14 19:10:38', '%Y-%m-%d %H:%M:%S')) # time.struct_time(tm_year=2022, tm_mon=7, tm_mday=14, tm_hour=19, tm_min=10, tm_sec=38, tm_wday=3, tm_yday=195, tm_isdst=-1)
'''
%Y----year
%m----month
%d----day
%H----hour
%M----minute
%S----second
%X == %H:%M:%S
'''