一. 模块的简单认识
模块就是我们把装有特定功能的代码进行归类的结果.从代码编写的单位来看我们的程序,从小到大的顺序:一条代码 < 语句块 < 代码块(函数,类) < 模块,我们目前写的所有的py文件都是模块,引入模块的方式:
1.import模块
2.from xxx import 模块
二. collections模块
collections模块主要封装了一些关于集合类的相关操作.比如,terable,Iterator等等.除了这些意外,collections还提供了一些除了基本数据类型以外的数据集合类型.Counter,deque,OrderDict,defaultdict以及namedtuple
1. Counter
counter是一个计数器,主要用来计数
from collections import Counter
print(Counter("哈哈哈你还好啊")) # 计算一个字符串中字符出现的个数 Counter({'哈': 3, '你': 1, '还': 1, '好': 1, '啊': 1})
lst = ["jay","jay","jay","哈哈","你好"]
dic = {"a":"你好","b":"你好","c":"真的好"}
l = Counter(lst)
c = Counter(dic.values())
print(l) # Counter({'jay': 3, '哈哈': 1, '你好': 1})
print(c) # Counter({'你好': 2, '真的好': 1})
2. deque 双向队列
1.先介绍两种数据结构 1.栈 2.队列
1.栈: FILO. 先进后出
2.队列:FIFO.先进先出
python中并没有给出Stack模块,所以我们写一个大概意思(这个版本有非常严重的并发问题,仅供粗略观看)
栈:
class StackFullException(Exception):
pass
class StackEmptyExcepiton(Exception):
pass
class Stack:
def __init__(self,size):
self.size = size
self.lst = []
self.top = 0 # 栈顶指针
def push(self,el): # 入栈
if self.top >= self.size:
raise StackFullException("栈已放满")
self.lst.insert(self.top,el)
self.top +=1
def pop(self): #出栈
if self.top == 0:
raise StackEmptyExcepiton("栈已放空")
self.top -= 1
el = self.lst[self.top]
return el
s = Stack(6)
s.push("1")
s.push("2")
s.push("3")
s.push("4")
s.push("5")
s.push("6")
print(s.pop()) #6
print(s.pop()) #5
print(s.pop()) #4
print(s.pop()) #3
print(s.pop()) #2
print(s.pop()) #1
deque: 双向队列
from collections import deque
d = deque() # 创建双向队列
d.append("1") # 在右侧添加
d.append("2")
d.append("3") # deque(['1', '2', '3'])
d.appendleft("0") # 在左侧添加 deque(['0', '1', '2', '3'])
print(d.pop()) # 从右边拿数据 3
print(d.popleft()) # 从左边拿数据 0
3.namedtuple 命名元组
给元组内的元素进行命名吗.这是一个元组(x,y).同时,我们还可以认为这是一个点坐标.这时,我妈们可以使用namedtuple对元素进行命名
from collections import namedtuple
nt = namedtuple("point",["x","y"])
p = nt(1,2)
print(p) # point(x=1, y=2)
print(p.x) # 1
print(p.y) # 2
3. orderdict 有序字典 , defaultdict默认值字典
字典的key是默认无序的在python3.3以前体现的很明显,时常打印出的字典顺序混乱,orderdict是有序的
from collections import OrderedDict
dic = OrderedDict()
dic["a"] = "你好"
dic["b"] = "哈哈"
print(dic) # OrderedDict([('a', '你好'), ('b', '哈哈')])
print(dic.get("a")) # 你好
print(dic.values()) # odict_values(['你好', '哈哈'])
print(dic["a"]) # 你好
4. defaultdict:
可以给字典设置默认值.当key不存在时.直接获取默认值:
from collections import defaultdict
dd = defaultdict(list)
print(dd["哇哈哈"]) # []
print(dd) # defaultdict(<class 'list'>, {'哇哈哈': []})
dd2 = defaultdict(lambda : 0) # callable 可调用的,字典是空的
print(dd2["优乐美"]) # 0
print(dd2) # defaultdict(<function <lambda> at 0x000001ECF0571E18>, {'优乐美': 0})
三. time时间模块
时间有三种:
结构化时间: gmtime() localtime()
时间戳: time.time() time.mktime()
格式化时间: time.strftime() time.strptime()
时间转化的思路:
数字 - > 字符串
struct_time = time.localtime(数字)
str = time.strftime("格式",struct_time)
字符串 - > 数字
struct_time = time.strptime(字符串,"格式")
num = time.mktime(struct_time)
时间模块是我们日常使用中经常用到的模块.
1.时间戳(timestamp).使用的是从1970年01月01日 00点00分00秒到现在一共经过了多少秒...使用float来表示
2.格式化时间(strftime).这个时间可以根据我们的需要对时间进行任意的格式化.
3.结构化时间(strct_time).这个时间主要可以把时间进行分类划分.比如.1970年01月01日 00点00分00秒 这个时间可以被细分为年,月,日...一大堆东西
时间戳我们已经见过了就是time.time().一般,我们不会把这样的时间展示给客户,所以,我们要对时间进行格式化操作
import time
s = time.strftime("%Y-%m-%d %H:%M:%S")
print(s)
日期格式化的标准:
%y 两位数的年份表示(00-99) %Y 四位数的年份表示(000-9999) %m 月份(01-12) %d 月内中的一天(0-31) %H 24小时制小时数(0-23) %I 12小时制小时数(01-12) %M 分钟数(00=59) %S 秒(00-59) %a 本地简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示 %j 年内的一天(001-366) %p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00-53)星期天为星期的开始 %w 星期(0-6),星期天为星期的开始 %W 一年中的星期数(00-53)星期一为星期的开始 %x 本地相应的日期表示 %X 本地相应的时间表示 %Z 当前时区的名称 %% %号本身
所有的转化都要通过结构化时间来转化,(结构化时间就是python中识别的时间)
import time t = time.localtime(1488484848) s = time.strftime("%Y-%m-%d %H:%M:%S") print(t) #结果(结构化时间): # time.struct_time(tm_year=2017, tm_mon=3, tm_mday=3, tm_hour=4, tm_min=0, tm_sec=48, tm_wday=4, tm_yday=62, tm_isdst=0) print(s) # 2018-12-26 21:14:55
如果让用户输入一个时间,我们来把它转化为我们数据库存储的时间戳,就要用到结构化时间,流程为
# 数据库里存储一个数字. 把它还原成我们的格式化时间
a = 0
# 先把这个时间戳转化成python中的结构化时间
# t = time.localtime(a) # 本地化的东八区的时间
t = time.gmtime(a) # 格林尼治时间
# 把一个结构化时间转化成格式化时间
s = time.strftime("%Y-%m-%d %H:%M:%S", t)
print(s)
现在我们举个例子用一下
s = "2018-12-26 21:16:33"
t = time.strptime(s,"%Y-%m-%d %H:%M:%S") # 转化为结构时间 print(time.mktime(t)) # 转化为时间戳
计算时间差
import time
true_time=time.mktime(time.strptime('2017-09-11 08:30:00','%Y-%m-%d %H:%M:%S'))
time_now=time.mktime(time.strptime('2017-09-12 11:00:00','%Y-%m-%d %H:%M:%S'))
dif_time=time_now-true_time
struct_time=time.localtime(dif_time)
print(struct_time)
print('过去了%d年%d月%d天%d小时%d分钟%d秒'%(struct_time.tm_year-1970,struct_time.tm_mon-1,
struct_time.tm_mday-1,struct_time.tm_hour,
struct_time.tm_min,struct_time.tm_sec))
四. functools
1.wraps
装饰器装饰的函数名字会变为inner,为了让装饰的函数名还原,我们用到了@wraps,这样打印出的函数名就还是原来的函数名了
from functools import wraps # 可以改变一个函数的名字, 注释...
def wrapper(fn):
@wraps(fn) # 把inner的名字改变成原来的func
def inner(*args, **kwargs):
print("前")
ret = fn(*args, **kwargs)
print("后")
return ret
return inner
@wrapper # func = wrapper(func)
def func():
print('哈哈哈')
print(func.__name__) # func
2. reduce 归纳.
# map 映射 reduce 归纳
print(list(map(lambda x: x**2, [i for i in range(10)])))
from functools import reduce
def func(a, b):
return a + b # 0+1 +4 +7+2+5+8+3+6+9 # 累加
# 会把我们每一个数据交给func去执行, 把默认值作为第一个参数传递给函数
# 第二个参数就是你这个序列中的第一个数据
# 接下来. 把刚才返回的结果作为第一个参数传递个a
# 继续吧刚才的结果给第一个参数. 把第三个数据传递给b
ret = reduce(func, [1,4,7,2,5,8,3,6,9])
# 工作流程
func(func(func(0, 1),4),7)
print(ret) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
print(reduce(lambda x, y:x + y, [i for i in range(101)]))
3. partial 偏函数
固定函数中某些参数的值
from functools import partial def chi(zhushi, fushi): print(zhushi, fushi) # 固定函数中某些参数的值 chi = partial(chi, fushi="辣鸡爪") chi("大米饭") # 大米饭 辣鸡爪
#坑
chi("大米饭","烤猪蹄") # 如果填入第二个参数就会报错, TypeError: chi() got multiple values for argument 'fushi'
chi("大米饭",fushi = "烤猪蹄") # 大米饭 烤猪蹄 如果第二个参数这样赋值,就可以把值传进去