本周总结
目录
本周总结
异常处理,生成器
异常常见类型
错误位置
错误类型:错误具体信息
命名错误 NameError
键错误 KeyError
缩进错误 IndenttationError
导入错误
未找到错误
语法错误 SyntaxError
索引错误 IndexError
异常处理语法结构
try:
需要监测的代码
except 错误类型 as e:
发生错误之后的解决方案
Exception 万能错误类型
try:
需要监测的代码
except Exception as e:
发生错误之后的解决方案
可以写多层
try:
需要监测的代码
except 错误类型1 as e:
发生错误类型1之后的解决方案
try:
需要监测的代码
except 错误类型2 as e:
发生错误2之后的解决方案
try:
需要监测的代码
except 错误类型3 as e:
发生错误3之后的解决方案
else:
try的子代码正常运行结束没有任何的报错后 再执行子代码
finally:
无论try的子代码是否报错 最后都要执行finally子代码
异常处理补充
1.断言
name = 'jason'
assert isinstance(name, str)
print('哈哈哈 我就说吧 肯定是字符串')
name.strip()
2.主动抛异常
name = 'jason'
if name == 'jason':
# 主动报错
raise Exception('老子不干了')
else:
print('正常走')
异常处理实战应用
1.异常处理能尽量少用就少用
2.被try监测的代码能尽量少就尽量少
3.遇到一些无法控制的情况报错才考虑使用比如:
比如访问网页,然后断网,需要报错
课堂练习:
# 使用while循环+异常处理+迭代器对象 完成for循环迭代取值的功能
l1 = [11, 22, 33, 44, 55, 66, 77, 88, 99]
# 1.先将列表调用__iter__转变成迭代器对象
l1 = l1.__iter__()
# 2.while循环让迭代器对象反复执行__next__
while True:
try:
print(l1.__next__())
except StopItertion as e:
break
生成器对象
1.本质
还是内置有__iter__和__next__的迭代器对象
2.区别
迭代器对象是解释器自动提供的
数据类型/文件对象>>>:迭代器对象
生成器对象是程序员编写出来的
代码,关键字>>>:迭代器对象(生成器)
3.创建生成器的基本语法
# 函数体代码中填写yield关键字
def my_iter():
print('哈哈哈 椰子汁很好喝')
yield
'''1.函数体代码中如果有yield关键字
那么函数名加括号并不会执行函数体代码
会生成一个生成器对象(迭代器对象)'''
res = my_iter()
'''2.使用加括号之后的结果调用__next__才会执行函数体代码'''
res.__next__()
'''3.每次执行完__next__代码都会停在yield位置 下次基于该位置继续往下找第二个yield'''
'''4.yield还有点类似于 return 可以返回返回值'''
自定义生成器对标range功能(一个参数 两个参数 三个参数 迭代器对象)
for i in range(1, 10):
print(i)
# 1.生成器
# 两个参数
def my_range(start_num, end_num=None, step=1):
if not end_num:
end_num = start_num
start_num = 0
while start_num < end_num:
yield start_num
start_num += step
yield冷门用法
def eat(name, food=None):
print(f'{name}准备用餐')
while True:
food = yield
print(f'{name}正在吃{food}')
res = eat('jaosn')
print(res.__next__())
res.send('汉堡') # 1.将括号内的数据传给yield前面的变量名2.再自动调用__next__
res.send('包子')
res.send('面条')
生成器表达式
# 说白了就是生成器的简化写法
# 元组生成式就是生成的一个生成器
t1 = (i * 2 for i in range(100))
面试题
大致知道流程即可
def add(n, i): # 普通函数 返回两个数的和 求和函数
return n + i
def test(): # 生成器
for i in range(4):
yield i
g = test() # 激活生成器
for n in [1, 10]:
g = (add(n, i) for i in g)
'''
0第一次for循环:
g = (add(n, i) for i in g) # 此时n = 1,但是没有被输出,继续下一次循环
第二次for循环:
g = (add(n, i) for i in (add(n, i) for i in g)) # 此时n = 10,被res = list(g)接收,后边第一个in后边等于加过一次的值,然后再相加
'''
res = list(g)
print(res)
'''不要深入研究 大致知道起始数即可'''
索引取值与迭代取值,模块基础
索引取值与迭代取值的差异
索引取值可以依据索引取值,不用按顺序,但是不能取无序类型
迭代取值只能按顺序一个一个取值,但是必须一个个取值,能取无序类型
ps:两者的使用需要结合实际应用场景
模块简介
1.模块的本质
内部具有一定的功能(代码)的py文件
2.python模块的历史
python刚开始的时候所有搞其他语言的程序员都看不起,后来随着项目的复杂程度越来越高,他们也用了
3.python模块的表现形式
1.py文件(也可以称为模块文件)
2.含有多个py文件的文件夹(根据模块功能的不同划分不同的文件夹存储)
3.已被编译为共享库或DLL的c或c++扩展(了解)
4.使用c编写并链接到python解释器的内置模块(了解)
模块的分类
自定义模块:我们自己写的
内置模块:python解释器自带的
第三方模块:python背后真正的大佬
导入模块的两种句式
import...
先在执行文件产生一个名称空间,然后导入模块文件,执行文件内产生一个模块名字,模块文件产生一个名称空间,里面存有一些名字,然后在执行文件内用模块名点的形式
form...import...
先在执行文件产生一个名称空间,然后导入模块文件内的名字,执行文件内产生模块内的一些名字,模块文件产生一个名称空间,里面存在一些名字,执行文件内的名字指向模块文件内的名字,执行文件直接名字调用就可以调用模块内的名字
导入模块补充说明
1.不要重复导入,导入只会导入一次
2.涉及到多个模块的导入
import a
import b
import a,b
如果模块功能相似度不高 推荐分开,相似度高可以放在一起
3.导入模块可以自定义名字,as一个简单易懂名字
4.import...导入名字之后每次都要用模块名.的方式调用模块
from...import...直接导入名字之后不用点直接调用,但容易跟执行文件内的名字冲突
这两种方式按需求选择
循环导入问题
1.两个文件之间彼此导入并相互使用各自名称空间中的名字 极容易报错
2.如何解决循环导入问题
1.确保名字在使用之前就已经准备完毕
2.我们以后在编写代码的过程中应该尽可能避免出现循环导入
判断文件类型
所有py文件都可以直接打印__name__对应的值
当py文件是执行文件的时候__name__对应的值是__main__
当py文件是被导入文件的时候__name__对应的值是模块名
模块的查找顺序
1.内存 如果内存中运行的有,先在内存中寻找
2.内置 如果内存中没有,则去内置模块中寻找
3.sys.path 如果内置中没有,则回去执行文件所在系统目录中寻找
绝对导入与相对导入
绝对导入
from mymd.aaa.bbb.ccc.ddd import name # 可以精确到变量名
from mymd.aaa.bbb.ccc import ddd # 也可以精确到模块名
相对导入
.在路径中表示当前目录
..在路径中表示上一层目录
..\..在路径中表示上上一层目录
不再依据执行文件所在的sys.path 而是以模块自身路径为准
from . import b
相对导入只能用于模块文件中 不能在执行文件中使用
'''相对导入使用频率较低 一般用绝对导入即可 结构更加清晰'''
包
文件夹内存有多个py文件的一个称呼,内有一个文件为__init__,python2必须要有,python3可有可无
包的具体使用,编程思想的转变,软件开发目录规范,python常用内置模块
包的具体使用
1.虽然python3对包的要求降低了 不需要__init__.py也可以识别 但是为了兼容性考虑最好还是加上__init__
1.直接导入包中的名字
from aaa import md1 md2
2.导入包名
import aaa
需要通过点的方式调用名字
编程思想的转变
1.按从上往下写,面条式
2.学会使用函数封装一些功能,然后调用函数在一些需要的地方
3.学会模块,根据功能的不同拆分成不同的文件
软件开发目录规范
1.bin 主要存放项目启动文件 start.py 可以放在bin目录下也可以放在项目根目录
2.conf 主要存放项目配置文件 settings.py 主要存放 项目默认配置,里面名字一般都是大写
3.core 主要存放项目核心文件 src.py 主要存放项目核心功能
4.interface 主要存放项目接口文件 user.py goods.py 根据业务逻辑需求对应的名字
5.db 主要存放项目数据 db_handle 主要存放数据库相关代码
6.lib 主要存放项目公共功能 common.py
7.log 主要存放项目日志文件 log.py
8.readme 主要存放项目相关说明
9.requerments.txt 主要存放项目相关模块及版本
常见内置模块之collections模块
from collections import tuplename
# 表示二维坐标系
res = tuplename('名字',['x','y'])
p1 = res(1, 2)
print(p1)
print(p1.x)
print(p1.y)
2.队列
队列与堆栈
队列:先进先出
堆栈:先进后出
队列和堆栈都是一边只能进一边只能出
常见内置模块之时间模块
time
import time
time.time() # 时间戳
time.sleep() # 阻塞填入的秒数
time.localtime() # 结构化时间
time.strftime('%Y-%m-%d %H:%M:-%s(or%X)') # 格式化时间
datetime
impotr datetime
datetime.datetime.now() # 年月日 时分秒
datetime.dateyime.today() # 年月日 时分秒
datetime.date.today() # 年月日
from datetime import date, datetime
date.today() # 年月日
datetime.utctime() # 年月日 时分秒
c = datetime.datetime(2017, 5, 23, 12, 20)
print('指定时间', c)
d = datetime.strptime('2017年9月30日星期六8时42分24秒','%Y年%m月%d日星期六%H时%M分%S秒')
print(d) # 2017-09-30 08:42:24
datetime.timedelta(day=3) # 定义一个三天后
常见内置模块之随机数模块
random
import random
random.random() # 随机产生一个0到1之间的小数
random.ranint() # 填入两个数字,起始数字,终止数字,随机产生一个两个数字之间的整数
random.randrange # 填入山歌数字,起始数字,终止数字,步长
random.choice() # 随机产生填入数据的一个''
random.choices() # 随机产生一个填入数据['']
random.sample() # 随机抽取指定样本数
random.shuffle(l1) # 随机打乱数据集
os,sys,json模块
os模块(重要)
关于操作系统的模块
import os
os.mkdir() # 创建单级文件,不可以创建多级目录
os.makedirs() # 创建多级目录,也可以创建单级目录
os.rmdir() # 删除单级目录,不能一次删除多级目录,只能删除空的单级目录
os.removedirs() # 删除多级目录,可以删除单级目录,只能删除空的多级目录
os.rename() # 重命名文件
os.remake() # 删除文件
os.path.dirname(__file__) # 动态找到当前执行目录的上级目录
os.chdir('..') # 返回上一级
os.getdcwd() # 获取当前目录
os.path.join() # 拼接路径
os.listdir() # 列举指定路径下的内容名称
os.path.exists(路径) # 判断文件路径是否存在
os.path.isfile() # 判断路径是否为文件
os.path.isdir() # 判断路径是否为目录
os.path.getsize() # 获取文件大小(字节)
sys模块
sys.path() # 当前系统目录
sys.path.join() # 把一个路径加入系统路径
sys.getrecursionlimit() # 获取python解释器默认最大递归深度
sys.setrecursionlimit() # 修改python解释器默认最大递归深度
sys.version # 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)
sys.platfrom # 平台信息 win32(了解)
sys.argv
if len(res) != 3:
print('执行命令缺少了用户名或密码')
else:
username = res[1]
password = res[2]
if username == 'jaosn' and password == '123':
print('jason你好 文件正常执行')
else:
print('您不是jason 无权执行该文件')
json模块
json模块也称为序列号模块 序列化可以打破语言限制实现不同编程语言之间数据交互
两个不同的编程语言之间不能直接进行交互,需要把一个格式转换成json格式,再把json格式转换成另一种编程语言
针对文件操作
json.dump()
json.load()
针对数据操作
json.dumps()
json.loads()
json模块实战
写入文件
拼接路径.json
with open() as f:
os.path.isdir()
dumps(user_dict, f)