绝对导入与相对导入
只要涉及到模块的导入,那么sys.path永远以执行文件为准
绝对导入
1.绝对导入就是以执行文件所在的sys.psth为起点路径,往下一层层的找
1.1 获取执行文件所在的路径:
import sys
print(sys.path)
1.2 如果执行文件aaa与被导入文件不在同一级别,需要用sys.path.append()添加被导入文件的绝对路径或者用import...from...句式
sys.path.append(r'D:\aaa\bbb\ccc\ddd')
from aaa.bbb.ccc.ddd import a
2.由于pycharm会自动将项目的根目录添加到sys.path中,所以查找模块肯定不会报错的方法永远是从根路径往下一层一层找
3.如果不是用pycharm运行,我们需要将项目的根目录添加到sys.path,我们可以借用os模块
相对导入
1.在模块导入模块中,可以不参考执行文件所在的路径,直接以当前模块文件路径为准
. 同级别(当前路径)
.. 上一级别(上一路径)
../.. 上上级别(上上一层路径)
2.在执行文件中不能够用相对导入,只能在模块文件中使用
3.相对导入在项目比较复杂的情况下,可能会出错,能少用就少用,推荐使用绝对路径
包
包的内部含有__init__.py文件,和文件夹差不多,只不过文件夹里面没有__init__.py
1.作用:内部可以存放多个py文件(模块文件),仅仅是为了更加方便的管理模块文件
2.使用
2.1 import 包名
直接导入包名,就只能使用__init__里面的名字(其实就等同于导入的是__init__.py文件)
2.2 from 包名 import 包里面的模块文件
上面的导入方式,可以跨过__init__.py直接导入包里面的模块文件
3.包在python3与python2的区别
python3解释器:其实文件夹里面有没有__init__.py已经无所谓了,都是包
python2解释器:文件夹下面必须要有__init__.py才能当做包
编程思想的转变
1.初级阶段--编写代码按照需求从上往下堆叠代码,有很多重复操作,并且全部代码在一个文件
2.函数阶段--将代码按照功能的不同封装成不同的函数,全部代码在一个文件
3.模块--根据功能不同拆分成不同的模块文件,分不在不同文件中
软件开发目录规范
1.bin文件夹--用于存储程序的启动文件>>>start.py
2.conf文件夹--用于存储程序的配置文件>>>settings.py
3.db文件夹--用于存储程序的数据文件>>>userinfo.txt >>> 以后可以被数据库软件替代
4.core文件夹--用于存储程序的核心逻辑>>>src.py
5.lib文件夹--用于存储程序的公共逻辑>>>common.py
6.log文件夹--用于存储程序的日志文件>>>log.log>>>log文件夹以后会被专门的日志服务替代
7.readme.txt文件--用于编写程序的说明、介绍、广告(类似于产品说明书)
8.requirements.txt文件--用于存储程序所需的第三方模块名称和版本
9.interface文件--用于存储程序的接口文件>>>core文件的扩展信息>>>order.py
ps:在编写软件的时候,不用完全遵循上面的文件名
常见的内置模块
collections模块
实质是以个包,用from…import…导入
namedtuple
生成可以使用名字来访问元素内容的tuple
from collections import namedtuple
point = namedtuple('个人信息','name age') # name与age只要中间分隔开,怎么表示都可以,比如用列表表示
print(point) # <class '__main__.个人信息'>
res1 = point('nana','18')
print(res1) # 个人信息(name='nana', age='18')
print(res1.name) # nana
deque双端队列
为了高效实现插入和删除操作的双向列表,适用于队列和堆栈
from collections import deque
q =deque()
print(q) # deque([])
q.append(1)
q.append(2)
q.append(3)
q.append(4)
q.append(5)
print(q) # deque([1, 2, 3, 4, 5])
print(q.popleft()) # 1
q.appendleft('x')
print(q) # deque(['x', 2, 3, 4, 5])
v = deque([1,2,3,4])
print(v) # deque([1, 2, 3, 4])
ps:deque不仅支持list的append()、pop(),还支持appendleft()和popleft()
OrderedDict
先添加的key-value排在前面,后添加的key-value排在后面
from collections import OrderedDict
a = OrderedDict([('name','nana'),('age',18)])
print(a) # OrderedDict([('name', 'nana'), ('age', 18)])
b = dict([('name','nana'),('age',18)])
print(b) # {'name': 'nana', 'age': 18}
defaultdict
基本上支持字典的功能,大多都支持defaultdict,最大区别在于:在dict中,如果引用的key不存在,就会报错,但defaultdict不会报错,而是返回一个默认值(可以是list、tuple、set、str等)
from collections import defaultdict
a = defaultdict()
print(a) # defaultdict(None, {})
b = defaultdict(name='nana',age = 18)
print(b) # defaultdict(None, {'name': 'nana', 'age': 18})
print(b['hobby']) # 报错
c = defaultdict(tuple)
print(c['a']) # () # 默认值是元组
有如下值集合 [11,22,33,44,55,66,77,88,99,90],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中{'k1':[], 'k2':[]}
from collections import defaultdict
a = defaultdict(k1=[],k2=[])
print(a) # defaultdict(None, {'k1': [], 'k2': []})
l1 =[11,22,33,44,55,66,77,88,99,90]
for i in l1:
if i >= 66:
a['k1'].append(i)
else:
a['k2'].append(i)
print(a) # defaultdict(None, {'k1': [66, 77, 88, 99, 90], 'k2': [11, 22, 33, 44, 55]})
Counter
用来跟踪值出现的次数,返回的是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value
list1 = ['jason','tony','oscar','jason','lisa','oscar']
from collections import Counter
res1 = Counter(list1)
print(res1) # Counter({'jason': 2, 'oscar': 2, 'tony': 1, 'lisa': 1})
time模块
在python中,表示时间有三种方式:时间戳(timestamp)、结构化时间(struct_time)、格式化时间(format string)
1.时间戳(timestamp):指的是从运行time.time()开始距离1970年1月1日0时0分开始的秒数,返回的数据类型是float
import time
print(time.time()) # 1657791536.4699469
2.结构化时间(struct_time):共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等),是计算机喜欢的格式
print(time.gmtime()) # time.struct_time(tm_year=2022, tm_mon=7, tm_mday=14, tm_hour=9, tm_min=49, tm_sec=54, tm_wday=3, tm_yday=195, tm_isdst=0)
print(time.localtime()) #time.struct_time(tm_year=2022, tm_mon=7, tm_mday=14, tm_hour=17, tm_min=49, tm_sec=54, tm_wday=3, tm_yday=195, tm_isdst=0)
3.格式化时间(format string):是人类比较喜欢的一种方式 eg:'2022-07-14'
print(time.strftime('%Y-%m-%d %X')) # 2022-07-14 17:45:46
print(time.strftime('%Y-%m-%d %H:%M:%S')) # 2022-07-14 17:46:13
结构化时间与时间戳之间的转换
1.时间戳变为结构化时间
1.1 time.gmtime(时间戳):是依据UTC时间
time1 = time.time()
print(time.gmtime(time1)) # time.struct_time(tm_year=2022, tm_mon=7, tm_mday=14, tm_hour=9, tm_min=56, tm_sec=47, tm_wday=3, tm_yday=195, tm_isdst=0)
1.2 time.localtime(时间戳):是依据本地时间
time2 = time.time()
print(time.localtime(time2)) # time.struct_time(tm_year=2022, tm_mon=7, tm_mday=14, tm_hour=17, tm_min=59, tm_sec=11, tm_wday=3, tm_yday=195, tm_isdst=0)
2.结构化时间转化为时间戳:time.mktime(结构化时间)
time3 = time.localtime()
print(time.mktime(time3)) # 1657792936.0
结构化时间与格式化时间之间的转换
1.结构化时间变为格式化时间:time.strftime('格式','结构化时间')
time4 = time.localtime()
print(time.strftime('%Y-%m-%d %X',time4)) # 2022-07-14 18:08:00
2.格式化时间变为结构化时间:time.strptime('格式化时间','字符串对应的格式')
time5 = time.strftime('%Y-%m-%d %X')
print(time.strptime(time5,'%Y-%m-%d %X')) # time.struct_time(tm_year=2022, tm_mon=7, tm_mday=14, tm_hour=18, tm_min=12, tm_sec=1, tm_wday=3, tm_yday=195, tm_isdst=-1)