上周内容回顾
-
编程与编程语言
-
python简介、解释器的安装、IDE编辑器安装
-
变量与常量
name = 'jason' HOST = '127.0.0.1'
-
数据类型
- 整型int
- 浮点型float
- 字符串str
- 列表list
- 字典dict
- 布尔值bool
- 元组tuple
- 集合set
-
运算符
x = x + 1 # 增量赋值 x += 1 # 解压赋值(多个值,一次给多个量) a, b = [111, 222] # 交叉赋值 m, n = n, m # 逻辑运算 and or not
-
流程控制
if 条件1: pass elif 条件2: pass else: pass while 条件: pass """ while + break #结束循环 while + continue #结束本次循环 """ for i in 可迭代对象: # 字符串、列表、字典... pass
-
文件操作
with open(file_path,mode,encoding='utf-8') as f: pass mode 默认只能操作文本文件 rt wt at 打开模式 t b 光标的移动 seek
本周内容概要
-
函数简介
-
函数的返回值
-
函数的参数
-
函数对象
-
名称空间与作用域
-
闭包函数与装饰器(了解)
-
迭代器、生成器
-
函数的递归、二分法、内置函数、匿名函数
-
模块(重点)
人工智能 数据分析 自动化运维、测试 网络爬虫 web开发 ...... python就是调包侠
-
面向对象/异常处理
今日内容详细
函数
"""
1.什么是函数
函数其实就是工具
如果没有函数就类似于每一次要使用锤子的时候
需要自己原地起锅烧火打造
2.为什么要有函数
为了节省人力、减少代码冗余
3.如何定义及使用函数
"""
# 函数的基本格式
"""
def func(参数1、参数2...):
'''函数的注释'''
函数体代码(就是真正的功能)
return 函数的返回值
1.def是定义函数的关键字
2.func是函数名 指向'内存空间'中的函数体代码
函数名的命名规范跟变量名一致
3.参数1、参数2在调用函数的时候'可能'需要传入的外部数据
4.函数的注释
用来解释函数的功能及使用的注意事项等等
5.函数体代码
实现该函数功能的实际代码
6.return返回值
在调用完函数之后 得到的结果
"""
#内存地址
def index():
async
a
print(index) #
函数有返回值,才能调用
s='my name is syy'
def my_len():
n=0
for i in s:
n+=1
return '哈哈'
res=my_len()
print(res) #哈哈
s='my name is syy'
def my_len():
n=0
for i in s:
n+=1
print(n)
my_len() #14
函数的返回值
# 关键字return
1.函数没有return 默认返回None
def index():
name = 'jason'
res=index()
print(res) #None
2.return后面跟什么 函数就返回什么
def index():
name = 'jason'
return 123
res=index()
print(res) #123
3.如果后面有多个数据 自动组织成'元组'返回
def index():
name = 'jason'
return 123,'a',{'b','c'}
res=index()
print(res) #(123, 'a', {'c', 'b'})
ps:如果一个函数有多个返回值 那么我们很有可能会直接使用解压赋值
def index():
name = 'jason'
return 123,'a',{'b','c'}
a,b,c=index()
print(a,b,c) #123 a {'b', 'c'}
"""
return可以返回值
并且在函数体内部一旦遇到return
函数会立刻结束,不会继续执行
"""
函数的参数分类
def index(x,y): # x和y就是形式参数
print(x,y)
index(1,2) # 1和2就是实际参数 将1赋值给x 将2赋值给y
"""
函数的参数分为两大类
形式参数
函数在定义阶段括号内指定的'变量名'叫形式参数
简称为形参
实际参数
函数在调用阶段括号内指定的'数据' 叫实际参数
简称为实参
两者之间的关系其实就相当于
形参是变量名
实参是变量值
传参'调用函数'其实就是给'形参赋值'
"""
函数的参数
#位置参数
def my_max(x,y):
print(x,y)
my_max(1,2) # 1 2
my_max(1) # 少传一个不行
my_max(1,2,3) # 多传一个也不行
列表长度
s=[0,1,3]
def my_len():
n=0
for i in s:
n+=1
print(n)
my_len()
3
多种字符类型的列表,可以使用手机参数优化代码
s=[0,1,3,'syy']
def my_len(s):
n=0
for i in s:
n+=1
print(n)
my_len(s)
4
单一变量打印出,直接打印
name='syy' 1
def index(): 2
print(name) 4
index() 3
syy
name='syy'
def index():
print(name)
sex=index()
print(type(sex)) #
多种类型变量的'列表打印出元组'
name = 'syy',1,[2,3],{4,5}
def index():
print(name)
index()
('syy', 1, [2, 3], {4, 5})
return返回值,同一级return之后不再执行
def index():
return 123,456,'syy',{'username':'syy'}
#...
res=index()
print(res)
(123, 456, 'syy', {'username': 'syy'})
形式参数
def index(x,y):
print(x,y)
index(1,2)
1 2
def index(x,y):
print(x,y)
index('1',2)
1 2 #
def index(x,y):
print(x,y)
index([1,2],3)
[1, 2] 3
def index(x,y):
print(x,y)
index({1,2},3)
{1, 2} 3
#实际参数,多少都不行
def index(x,y):
print(x,y)
index(1,2,3)
位置参数(比较大小)
def my_max(x,y):
if x > y:
return x
return y
res=my_max(1,2)
print(res)
默认参数
def register(name,gender='male'):
print(name,gender)
register('a') #a male
def register(name,gender='male'):
print(name,gender)
register('a','b') #a b
关键字参数,关键字参数要放在关键字参数的后面,且不能重复赋值
def register(name,gender):
print(name,gender)
register(1,2)
1 2
def register(name,gender):
print(name,gender)
register(name=2,gender=1)
def register(name,gender):
print(name,gender)
register(2,gender=1)
"""
*号在形参中 用来接收多余的位置参数
组织成'元组'的形式赋值给后面的变量名
**号在形参中 用来接收多余的关键字参数
组织成字典的形式赋值给后面的变量名
虽然*和**后面的变量名没有固定的值,但是一般情况下我们会默认写成
*args
**kwargs
"""
可变长参数(变量名随意*args **kwargs)
接收多余的'位置参数'(打印出元组)
def index(*a,er):
print(a,er)
index(1,2,er='a') #(1, 2) a
def index(x,*a):
print(x,a)
index(1,2,3,4) #1 (2, 3, 4)
接收多余的'关键字参数'(打印出字典)
def index(d,*a,**k):
print(d,a,k)
index(1,2,3,x=1,y=2,z=3) #1 (2, 3) {'x': 1, 'y': 2, 'z': 3}
def index(*args,**kwargs):
print(args,kwargs)
index(1,2,3,4,5,6,7,8,9)
index(x=1,y=2,z=3)
index(1,2,3,4,5,6,7,8,9,x=1,y=2,z=3)
index(1,2,3,4,5,(6,7,8,9), {'x':1, 'y':2, 'z':3})
(1, 2, 3, 4, 5, 6, 7, 8, 9) {}
() {'x': 1, 'y': 2, 'z': 3}
(1, 2, 3, 4, 5, 6, 7, 8, 9) {'x': 1, 'y': 2, 'z': 3}
(1, 2, 3, 4, 5, (6, 7, 8, 9), {'x': 1, 'y': 2, 'z': 3}) {}
"""
*号在实参中
能够将列表、字符串打散 将打散之后的元素一个个传入
**号在实参中
能够将字典打散成关键字参数
"""
def index(*args,**kwargs):
print('args:',args)
print('kwargs:',kwargs)
l=[1,2,3,4,5,6,7,8,9]
index(l)
args: ([1, 2, 3, 4, 5, 6, 7, 8, 9],)
kwargs: {}
#*能够将列表打散,放到元组
def index(*args,**kwargs):
print('args:',args)
print('kwargs:',kwargs)
l=[1,2,3,4,5,6,7,8,9]
index(*l)
args: (1, 2, 3, 4, 5, 6, 7, 8, 9)
kwargs: {}
#*将字典打散,放到字典
def index(*args,**kwargs):
print('args:',args)
print('kwargs:',kwargs)
d={'a':1,'b':2}
index(**d)
kwargs: {'a': 1, 'b': 2}
#**将字典打散,放到字典
def index(*args,**kwargs):
print('args:',args)
print('kwargs:',kwargs)
index(username='syy',passwd=123)
args: ()
kwargs: {'username': 'syy', 'passwd': 123}
函数对象
1 函数名可以'被当做变量名'赋值给其他变量
def index():
print('from index')
index()
print(index)
f=index
f()
from index
from index
2 函数名可以'当做函数的参数'传入
def index():
print('from index')
def func(x):
print(x)
x()
func(index)
from index
3 函数名还可以当做'函数的返回值'(******)
def bar():
print('from bar')
def index():
print('from index')
return bar
index()
res=index()
print(res)
res()
# 4 函数名还可以作为容器类型(能够存储多个元素的数据类型)的元素
def bar():
print('from bar')
l = [1,2,3,4,5,6,bar]
print(l)
l[-1]()
[1, 2, 3, 4, 5, 6, ]
from bar
函数的嵌套定义、调用
def index():
print('from index')
def inner():
print('from inner')
inner()
index()
from index
from inner
#执行流程:定义,调用,执行
名称空间与作用域
"""
名称空间
name = 'jason' 名称空间其实就是用来存储'名字和值'绑定关系的地方
内置名称空间
python解释器启动之后就会'自动创建'的名称空间
这个里面存放的是python解释器事先给你准备好的一些名字
len、max、min...
print(len)
全局名称空间(使用最多)
在文件级别定义的
name = 'jason'
局部名称空间
在'函数体内部'定义的
调用函数的时候创建 函数结束之后'销毁'
"""
# 名称空间的查找顺序
len = '有点饿了2'
def index():
len = '我也很饿1'
print(len)
index()
print(len)
我也很饿1
有点饿了2
1.如果你(print)当前在全局的话
这个时候查找顺序是
全局 >>> 内置
2.如果你当前在局部
这个时候查找顺序是
局部 >>> 全局 >>> 内置
# 作用域(作用范围)
"""
局部作用域
局部名称空间
全局作用域
内置、全局名称空间
"""
# 自己在自己的局部名称空间中创建了一个名字name
name = 'jason'
def index():
name = 'frank'
index()
print(name)
# 局部修改全局,global声明我要修改全局里面的name而不是创建
name = 'jason'
def index():
global name
name = 'frank'
index()
print(name)
# 局部修改局部(外围生效)
def func():
name = 'haoda'
def index():
name = 'jason'
def inner():
# nonlocal name
name = 'egon'
print(name)
inner()
print(name)
index()
print(name)
func()
egon
jason
haoda
# 局部修改局部(nonlocal定义本机局部,修改上一级)
name=1
def func():
name = 'haoda'
def index():
name = 'jason'
def inner():
nonlocal name
name = 'egon'
print(name)
inner()
print(name)
index()
print(name)
func()
egon
egon
haoda
小补充
画图理解
m = 1
n = 2
m = n
n = m
print(m,n)
2 2
# 交叉赋值
m = 1
n = 2
tmp = m
m = n
n = tmp
print(m,n)
2 1
#交叉赋值
m = 1
n = 2
m, n = n,m
print(m,n)
#pass用法
def register():
pass
def register1():
...
装饰器
"""
装饰器
在不改变被装饰对象(函数)
1.调用方式
2.源代码
的基础之上给被装饰对象(函数)添加'额外的功能'
"""
# 提前书写装饰器的固定代码
def outer(func):
def inner(*args,**kwargs):
print('在执行被装饰函数之前你可以添加的额外操作')
res = func(*args,**kwargs)
print('在执行被装饰函数之后你可以添加的额外操作')
return res
return inner
#套用装饰器
@outer
def index():
print('from index')
index()
在执行被装饰函数之前你可以添加的额外操作
from index
在执行被装饰函数之后你可以添加的额外操作
# 有参装饰器
def login_auth(x):
def outer(func):
def inner(*args,**kwargs):
print('在执行被装饰函数之前你可以添加的额外操作')
res = func(*args,**kwargs)
print('在执行被装饰函数之后你可以添加的额外操作')
return res
return inner
return outer
@login_auth(123)
def index():
print('from index')
index()
在执行被装饰函数之前你可以添加的额外操作
from index
在执行被装饰函数之后你可以添加的额外操作
递归
"""
递归
函数在'调用阶段' 自己直接或者间接的'又调用了自己'
"""
def index():
print('from index')
index()
index()
import sys
print(sys.getrecursionlimit())
"""
1.递归的次数必须是有限的(递归深度)
2.每一次递归都要比上一次复杂度更低
递归包含两个过程
递推
回溯
"""
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18
#递归加2(一个数值循环加上一个固定值)
def get_age(num):
if num == 1:
return 18
return get_age(num-1) + 2
res=get_age(5)
print(res)
26
# 递归取值
l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11]]]]]]]]]]]
def get_value(l):
for i in l:
if not isinstance(i,list):
print(i)
else:
get_value(i)
get_value(l)
1
2
3
4
5
6
7
8
9
10
11
二分法
"""
算法
其实就是解决问题的'高效率的方法'
"""
"""
二分法
参考的数据必须有大小顺序
"""
#判断列表中存不存在某值,同时记录循环次数(数据可以无序)
num_list = [13,15,17,23,55,78,98,123,234,345,453,567,657,713,890]
num=453
count=0
for i in num_list:
count=count+1
if i == num:
print('列表存在该值')
print('循环次数:',count)
列表存在该值
循环次数: 11
num_list = [13,15,17,23,55,78,98,123,234,345,453,567,657,713,890]
target_num = 453
count=0
def search(num_list, target_num):
# 代码优化 值不存在的情况
if len(num_list) == 0:
print('要找的数字不在这个列表内')
return
# 先获取中间索引值(取左)
middle_index = len(num_list) // 2
# 判断要找的数字于中间索引对应的值孰大孰小
count=count+1
if target_num > num_list[middle_index]:
# 截取右半边大的部分
num_list = num_list[middle_index + 1:]
search(num_list, target_num)
elif target_num < num_list[middle_index]:
# 截取左半边小的部分
num_list = num_list[0:middle_index]
search(num_list, target_num)
else:
print('find it!')
三元表达式、生成器
# 判断两个数谁大
def index(x,y):
if x > y:
print(x)
else:
print(y)
# 三元表达式
"""
三元表达式只适用于两选一的情况
x if x > y else y
如果if后面的条件成立那么返回if前面的值
如果条件不成立那么返回else后面的值
"""
函数
def index(x,y):
return x if x > y else y
res=index(1,100)
print(res)
index(1,100)
变量
x = 1
y = 1
res = x if x > y else (y if y > x else '相等')
print(res)
回车执行
name = input('username>>>:')
res = 'NB' if name == 'syy' else '垃圾'
print(res)
# 列表生成式 .append
l = ['jason','frank','tony','tom','haoda']
new_l = []
for name in l:
new_l.append(name+'_NB')
print(new_l)
['jason_NB', 'frank_NB', 'tony_NB', 'tom_NB', 'haoda_NB']
# 列表生成式
l = ['jason','frank','tony','tom','haoda']
res = [name+'_DSB' for name in l]
print(res)
['jason_NB', 'frank_NB', 'tony_NB', 'tom_NB', 'haoda_NB']
选择追加(从后向前)
l = ['jason','frank','tony','tom','haoda']
res = [name+'_DSB' for name in l if name=='jason']
print(res)
['jason_DSB']
# 生成器表达式(全部取值)(母鸡生蛋)
l = ['jason','frank','tony','tom','haoda']
res = (name+'_DSB' for name in l)
print(res)
for i in res:
print(i)
at 0x0000024DA6A7B7D8> #内存地址
jason_DSB
frank_DSB
tony_DSB
tom_DSB
haoda_DSB
部分取值(依次取值)
l = ['jason','frank','tony','tom','haoda']
res = (name+'_DSB' for name in l)
print(res.__next__())
print(res.__next__())
print(res.__next__())
jason_DSB
frank_DSB
tony_DSB
部分取值(跳过取值)
l = ['jason','frank','tony','tom','haoda']
res = (name+'_DSB' for name in l)
print(res.__next__())
res.__next__()
print(res.__next__())
jason_DSB
tony_DSB
"""
生成器能够节省内存 是我们程序优化阶段需要考虑的事情
"""
匿名函数
"""
没有名字的函数
一般情况下都是结合'内置函数'一起使用的
"""
#使用lambda,数字相加
res = lambda x,y:x+y
ret = res(1,2)
print(ret)
3
一般方法
def index(x,y):
return x + y
res=index(1,2)
print(res)
3
#ascII与数字的对应关系
print(chr(65))
A
print(chr(90))
Z
print(chr(97))
a
print(chr(122))
z
必须是字符串类型
print(ord('A'))
print(ord('Z'))
print(ord('a'))
print(ord('z'))
65
90
97
122
字典取key,max本质是for循环
salaries = {
'egon':30000,
'jason':888888888,
'nick':2000,
'tank':100
}
res=max(salaries)
print(res)
tank
#指定key取值
salaries = {
'egon':30000,
'jason':888888888,
'nick':2000,
'tank':100
}
def index(name):
return salaries[name]
res=index('jason')
print(res)
888888888
#lambda返回最大值(value)对应的key
salaries = {
'egon':30000,
'jason':888888888,
'nick':2000,
'tank':100
}
res = max(salaries,key=lambda name:salaries[name])
print(res)
jason
#使用函数取值
salaries = {
'egon':30000,
'jason':888888888,
'nick':2000,
'tank':100
}
def index(name):
return salaries[name]
res = max(salaries,key=index)
print(res)
jason
内置函数
参考网站
#abs()
res=abs(-1)
print(res)
1
#all(),全部为true才为true
l=[3,2,1,0]
res=all(l)
print(res)
False
l=[3,2,1]
res=all(l)
print(res)
True
#any(),有一个true就是true
l=[3,2,1,0]
res=any(l)
print(res)
True
l=[0]
res=any(l)
print(res)
False
#二进制转换
num=666 #十进制
print(bin(num)) #二进制
print(oct(num)) #八进制
print(hex(num)) #十六进制
0b1010011010
0o1232
0x29a
#转换为二进制,int既可以把进制转为二进制,又可以把字符类型转为整形
print(int('0b1010011010',2))
print(int('0o1232',8))
print(int('0x29a',16))
666
666
666
#bytes
num=666
sex=bytes(num)
print(sex)
b'\x00\x00\x00\x00\x00\x00\'
#callable,判断一个字符能不能加括号执行
s='哈哈'
def index():
pass
print(callable(s))
print(callable(index))
False
True
#chr,把数字转为ASCII码
print(chr(65))
A
print(chr(90))
Z
print(chr(97))
a
print(chr(122))
z
#枚举,开始的索引:value
lll = ['jason','frank','tony','tom','haoda']
for i,j in enumerate(lll,2):
print(i,j)
2 jason
3 frank
4 tony
5 tom
6 haoda
#eval exec,必须给一个字符类型
res="print('hello world')"
eval(res)
exec(res)
hello world
hello world
#eval不可以执行逻辑性代码,exec可以执行逻辑性代码
res1 = """
for i in range(10):
print(i)
"""
# eval(res1)
exec(res1)
#区分老母鸡,object(老母鸡)
lll = ['jason','frank','tony','tom','haoda']
res = filter(lambda x:x == 'jason',lll)
print(res)
#fileter,在lambda中过滤,list本身是一个for循环
lll = ['jason','frank','tony','tom','haoda']
res = filter(lambda x:x == 'jason',lll)
print(list(res))
['jason']
#isinstance(lll,list),判断lll是不是列表
lll = ['jason','frank','tony','tom','haoda']
a=isinstance(lll,list)
print(a)
True
#round,五舍六入
res=round(4.5)
print(res)
4
模块
"""
其实就是一系列功能的集合体
1.内置模块
2.第三方模块
3.自定义模块
"""
# 导入模块的方式
1.import...
2.from...import...
# 起别名
import mymd as md
md.index()
3.from mymd import *
index()
print(name)
# 如何导入第三方模块
1.利用pip3下载对应的模块
pip install djiango
2.然后再利用上述import或者from import导入即可
常用模块
"""
将mymd里面所有的资源导入到当前文件
导入模块其实就是在那个文件从上往下执行该模块代码
重复导入一个模块 只会生效一次
"""
#模块分类
1.本地
2.网络
#导入相同目录另一个文件中的所有模块
import mm
def index():
print('我是2函数')
index()
我是2函数
#小心需要mm.index
import mm
print('---')
print(mm.index())
print('---')
print(mm.name)
我是2函数
---
我是2函数
None
---
syy
#导入相同目录另一个文件中的指定模块,不需要 mm.name
from mm import name
print(name)
我是2函数
syy
#as,给文件取别名,小心需要md.name
import mm as md
print(md.name)
我是2函数
syy
#不再需要 mm.name,直接使用name
from mm import *
index()
print(name)
我是2函数
我是2函数
syy
# 时间模块,1970年到现在的秒数
import time
print(time.time())
1596187405.7827623
sleep睡觉
import time
print(time.time())
time.sleep(3)
print('额')
时间戳
import time
print(time.strftime('%Y-%m-%d'))
print(time.strftime('%Y-%m-%d %X'))
print(time.strftime('%Y-%m-%d %H:%M:%S'))
2020-07-31
2020-07-31 17:26:29
2020-07-31 17:26:29
有time就显示年月日时分秒
import datetime
print(datetime.datetime.now())
print(datetime.date.today())
2020-07-25 16:47:24.534835
2020-07-25
# timedelta对象,可以对时间进行运算操作
import datetime
#获取本地时间,年月日
tday=datetime.date.today()
#定义操作时间 day=7 也就是说可以对另一个时间对象+/- 7天
tdelta = datetime.timedelta(days=7)
# 打印今天的日期
print('今天的日期:{}'.format(tday))
# 打印七天后的日期
print('从今天向后推7天:{}'.format(tday + tdelta))
# 总结:日期对象与timedelta之间的关系
今天的日期:2020-07-31
从今天向后推7天:2020-08-07
# 小练习 计算举例今年过生日还有多少天
import datetime
birthday = datetime.date(1994, 11, 13)
now_date = datetime.date.today()
days = now_date - birthday
print('生日:{}'.format(birthday))
print('今天的日期:{}'.format(now_date))
print('距离生日还有{}天'.format(days))
生日:1994-11-13
今天的日期:2020-07-31
距离生日还有9392 days, 0:00:00天
# 随机模块random
import random
# 1到6随机的整数(筛子)
print(random.randint(1,6))
# 0到1之间的小数
print(random.random())
l = [1,2,3,4,5,6,7,8,9]
#重新排序(洗牌),shuffle后面字符类型要相同
random.shuffle(l)
print(l)
6
0.452822393545086
[7, 3, 4, 1, 5, 9, 2, 8, 6]
#随机取值(抽奖),choice的字符类型必须要相同
import random
l = ['1号技师','2号技师','3号技师','4号技师','5号技师']
res = random.choice(l)
print(res)
2号技师
筛子
import random
l = [1,2,3,4,5]
res = random.choice(l)
print(res)
3
# 搜狗笔试题
# 生成五位数的随机验证码 要求
# 每一位都是可以是数字、小写字母、大写字母
import random
code = ''
for i in range(5):
# 每次都随机产生一个数字
random_int = str(random.randint(0,9))
# 每次都随机产生一个小写字母
random_lower = chr(random.randint(97,122))
# 每次都随机产生一个大写字母
random_upper = chr(random.randint(65, 90))
# 三者选一个
temp = random.choice([random_int,random_lower,random_upper])
# 拼接
code += temp
print(code)
3CJPp
os与sys
os跟操作系统打交道的
sys是跟解释器打交道的
#递归创建
import os
res=os.makedirs('dirname1/dirname2')
print(res)
#递归删除
import os
res=os.removedirs('dirname1/dirname2')
print(res)
#创建单级目录
import os
res=os.mkdir('dirname')
print(res)
#删除单级目录
import os
res=os.rmdir('dirname')
print(res)
#ll -a
import os
res=os.listdir('F:\笔记\正课1-10')
print(res)
#删除一个文件
import os
res=os.remove('F:/aaa.txt')
print(res)
#重命名文件/目录
import os
res=os.rename("1.py","2.py")
print(res)
#运行shell命令,直接显示
import os
res=os.system("dir:")
print(res)
#cd
import os
res=os.chdir("F:/")
print(res)
#pwd
import os
res=os.getcwd(())
print(res)
#获取当前的工作目录
import os
res=os.getcwd()
print(res)
E:\1.py
#拼接路径,拼接路径的时候 不同的操作系统分隔符是不一样
import os
res=os.path.join(path1[, path2[, ...]])
print(res)
#最大递归深度(不固定)
import sys
print(sys.getrecursionlimit())
序列化模块
"""
json格式数据,json模块
1、不同语言之间的数据交互
2、其实就是一堆字符串
3. json格式数据,打印显示双引号
文本内的内容就是一堆字符串
文件可以作为小型的数据库
数据基于网络传输:
数据 --json.dumps()--> 文本(字符串)--encode()--> 二进制
--> 网络传输 -->
decode()--> 文本(字符串)-->json.loads()--> 数据
"""
# 将数据转成字符串的过程 就叫序列化
import json
d = {'username': 'jason','password': 123}
res = json.dumps(d)
print(res,type(res))
{"username": "jason", "password": 123}
# 将json格式的字符串转换成编程里面的数据类型 ,反序列化
import json
d = {'username': 'jason','password': 123}
res = json.dumps(d)
res1 = json.loads(res)
print(res,type(res1))
#直接将字典写入文件,创建,
过程:字典转化为字符串 -- 创建文件 -- 写入字符串
d = {'username': 'jason','password': 123}
with open('a.txt','w',encoding='utf-8') as f:
json.dump(d,f)
#读文件中的内容
d = {'username': 'jason','password': 123}
with open('a.txt','w',encoding='utf-8') as f:
res=json.load(f)
print(res,type(res))
加密模块hashlib
md5解密
# 加密模块,数据必须是bytes类型
import hashlib
md5 = hashlib.md5()
md5.update(b'hello world')
res = md5.hexdigest()
print(res)
5eb63bbbe01eeed093cb22bb8f5acdc3
#分开加密,数值相同,update无论你是一次性传入还是分批次传入,只要传入的数据是一样的 那么结果肯定一样
import hashlib
md5 = hashlib.md5()
md5.update(b'holle world')
md5.update(b'h')
md5.update(b'ell')
md5.update(b'o world')
res = md5.hexdigest()
print(res)
5eb63bbbe01eeed093cb22bb8f5acdc3
# 加盐
import hashlib
md5 = hashlib.md5()
md5.update(b'12321 hello world')
res = md5.hexdigest()
print(res)
a4d3e9289d08db533690bbfd342ae9e5
# 动态加盐,动态:用户名 当前时间
import hashlib
md5 = hashlib.md5()
md5.update(b'xx hello world')
res = md5.hexdigest()
print(res)
日志模块
参考网站
#日志级别
import logging
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。
#日志基本格式
import logging
file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
handlers=[file_handler,],
level=logging.ERROR
)
logging.error('你好')
2020-07-31 20:22:43 PM - root - ERROR -mm: error message
#日志切割
import time
import logging
from logging import handlers
sh = logging.StreamHandler()
rh = handlers.RotatingFileHandler('myapp.log', maxBytes=1024,backupCount=5)
fh = handlers.TimedRotatingFileHandler(filename='x2.log', when='s', interval=5, encoding='utf-8')
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
handlers=[fh,sh,rh],
level=logging.ERROR
)
for i in range(1,100000):
time.sleep(1)
logging.error('KeyboardInterrupt error %s'%str(i))
re模块(正则)
"""
正则表达式
通过书写一对看不懂的符号从一大堆文本中
匹配出你想要的内容
它是一门独立的语言
推荐书籍:<<正则指引>>
"""
#re.findall,\d 匹配数字
import re
res='syy 666'
ret=re.findall('\d',res)
print(ret)
['6', '6', '6']
贪婪匹配
import re
res='syy 666'
ret=re.findall('\d+',res)
print(ret)
['666']
#re.match,只能匹配第一个字符
import re
res='syy 666'
ret=re.match('s',res)
print(ret)
<_sre.SRE_Match object; span=(0, 1), match='s'>
#re.match,可以匹配任意字符
import re
res='syy 666'
ret=re.search('y',res)
print(ret)
<_sre.SRE_Match object; span=(1, 2), match='y'>
打印出'字符'
import re
res='syy 666'
ret=re.search('y',res)
print(ret.group())
y