常见的内置函数、可迭代对象、迭代器对象、异常捕获、异常捕获的用途、生成器对象、模块、绝对导入与相对导入、包的概念、模块
学习python第五周总结
一、常见的内置函数
提前定义好的,直接可以使用
内置函数 | 功能 |
---|---|
abs() | 判断的容器类型中所有数据值都为True,结果就是True |
all() | 判断的容器类型中所有数据值都为True,结果就是True |
any() | 判断的容器类型中只要有一个数据值为True,结果就是True |
bin() | 十进制转换为二进制 |
oct() | 十进制转换为八进制 |
hex() | 十进制转换为十六进制 |
int() | 类型转换 其他进制转十进制 |
bytes() | 类型转换 |
callable() | 判断某个变量是否可以加括号调用 |
chr() | 依据ASCII码表实现数字对字符的转换 |
ord() | 依据ASCII码表实现字符对数字的转换 |
dir() | 获取对象内部可以通过句点符获取的数据 |
divmod() | 获取除法之后的整数和余数 |
enumerate() | 枚举,循环打印出数据值并且对应的索引值默认是从0开始,可以自定义 |
eval() | 不识别复杂结构的代码,只能识别最简单的python代码并执行 |
exec() | 可以识别复杂结构python代码并执行 |
hash() | 返回一串随机的数字(哈希值) |
help() | 查看帮助信息 |
isinstance() | 判断某个数据是否属于某个数据类型 |
pow() | 幂指数 |
round() | 四舍五 |
二、可迭代对象
1.迭代如何理解
迭代就是更新换代,每次迭代都需要基于上一次的成果
2.怎么判断可迭代对象
通过句点符直接能够点出来有__
init__
方法的都叫可迭代对象,读法为双下XXX
3.属于可迭代对象的有?
字符串、字典、元组、集合、列表、文件对象
4.关于可迭代对象的额外补充
能够支持for循环取值
三、迭代器对象
1.怎么判断迭代器对象
通过句点符直接能够点出来有__
iter__
和__
next__
的方法都叫迭代器对象
2.可迭代对象与迭代器对象的关系
可迭代对象调用__
iter__
方法之后就会变成迭代器对象
迭代器对象调用__
iter__
方法无论多少次还是迭代器对象
3.迭代器对象迭代取值过程
先调用双下iter转换成迭代器对象,然后再使用双下next,每次只能取到一个值,取完之后再取的话就会报错
如果是在for循环里的话,不会出现报错的问题,因为for循环内部会去处理这个报错的现象
如果在while循环中的话,while后面会跟它的结束条件,所以也处理里它报错的问题
4.关于迭代器对象的额外补充对象
可以简写为iter(变量名)、next(变量名)
可迭代对象、迭代器对象通过答应操作是无法直接看出内部数据的情况的,相当于一个工厂,要数据的时候临时给。
5.迭代取值与索引取值的区别
-
迭代取值的优缺点
优点:是一种通用的取值方式
缺点:取值一旦开始只能往前取值不能回退取值
-
索引取值的优缺点
优点:可以随意的反复的获取任意数据值
缺点:针对无序的容器类型无法取值
6.for循环的本质
语法结构:
for 变量名 in 可迭代对象:
for循环体代码
- for会自动将in后面的数据调用
__
iter__
()变成迭代器对象 - 之后每次循环调用
__
next__
()取值 - 最后没有值
__
next__
()会报错 for能够自动处理该错误 让循环正常结束
四、异常捕获
1.什么是异常?
异常就是在运行的过程中出现了问题导致整个程序结束,就是我们经常说的bug
2.异常的结构
- 错误出现的所在行,就是有关键字line的那句话,它会提示你是哪一行出现了错误,精准的定位到那一行,可以点它那个链接会直接跳转到跑错的那一行
- 最底下有一行,冒号左边是错类型,冒号右边的是具体的报错原因,改bug的关键,如果看不懂报错的信息,不知道该怎么修改,可以复制到百度,会有这种报错的人,可以参考别人的对自己的进行修改
3.异常的类型
NameError、IndexError、KeyError、SyntaxError、TypeError
4.异常的分类
- 语法结构:不允许出现的,出现的话在你写的时候就会出现标红的信息,要立马修改过来再往下面写
- 逻辑错误:允许出现的,在把整个程序写完之后,表面可能看起来没错,没有标红的现象,可以在提交之前,自己运行几遍,自己先修改修改,查看一下有没有逻辑上的错误
五、异常捕获的用途
1.什么情况下会使用到异常捕获去处理?
当代码不确定什么时候会出现报错的情况下,可以使用异常捕获去处理,异常捕获的核心思想就是相当于是提前预测可能出现的问题并提前给出处理的措施
2.异常捕获的代码实现
- 语法架构
'''基本语法结构'''
try:
可能会出错的代码(被try监控)
except 错误类型1 as e: # e就是具体错误的原因
对应错误类型1的解决措施
except 错误类型2 as e: # e就是具体错误的原因
对应错误类型2的解决措施
except 错误类型3 as e: # e就是具体错误的原因
对应错误类型3的解决措施
except 错误类型4 as e: # e就是具体错误的原因
对应错误类型4的解决措施
'''万能异常处理结构'''
try:
# name
# d = {'name':'jason'}
# d['pwd']
123 + 'hello'
except Exception as e: # 万能异常方式1
print(e)
except BaseException as e: # 万能异常方式2
print(e)
- 异常捕获其他操作补充
'''else与finally'''
try:
name
except Exception as e:
print('你出错了 你个小垃圾')
else:
print('try监测的代码没有出错的情况下正常运行结束 则会执行else子代码')
finally:
print('try监测的代码无论有没有出错 最后都会执行finally子代码')
'''断言'''
name = 'jason' # 通过一系列的手段获取来的数据
assert isinstance(name, list) # 断言数据属于什么类型 如果不对则直接报错 对则正常执行下面的代码
print('针对name数据使用列表相关的操作')
'''主动抛异常'''
name = input('username>>>:').strip()
if name == 'jason':
# raise NameError('jason来了 快跑!!!')
raise Exception('反正就是不能过')
else:
print('不是jason 那没事了')
- 注意:异常捕获能少用就少用,被try检测的代码能少就少
六、生成器对象
1.生成器的本质思想
本质来说它也是迭代器,只不过是我们自己定义的,目的是为了优化代码,是一种不依赖索引取值的通用方式,可以节省数据类型的内存占用空间
2.生成器的结构
def index():
print('ababa')
yield 111, 222, 333
print('bababa')
yield 222
print('aaabbb')
yield 333
3.yield用法
- 当函数代码有yield关键字那么函数名第一次加括号调用的时候不会执行函数体代码,而是由普通的函数变成了迭代器对象
- yield可以在函数体代码中出现多次,每次调用__next__方法都会从上往下执行直到遇到yield代码停留在此处
- yield后面如果有数据值,则会像return一样返回出去,如果有多个数据值逗号隔开,那么也会自动组织成元组返回
- 可以与send()一起用,通过传值然后并自动调用
__
next__
方法
4.生成器表达式
主要用的作用在于一次性生成一个含有多个数据值的数据集合并且不占用太多空间
l1 = (i**2 for i in range(10) if i > 3)
print(l1) # <generator object <genexpr> at
七、模块
1.关于模块的介绍
模块可以看成是一系列功能的结合体,使用模块就相当于拥有了这结合体内的所有功能
2.模块的分类
- 内置模块:解释器自带的,直接就可以使用的模块
- 自定义模块:自己写的模块
- 第三方模块:别人写的模块,存在于网络上,使用之前需要提前下载
3.模块的表现形式
- py文件(py文件也可以称之为是模块文件)
- 含有多个py文件的文件夹(按照模块功能的不同划分不同的文件夹存储)
- 已被编译为共享库或DLL的c或C++扩展(了解)
- 使用C编写并链接到python解释器的内置模块(了解)
4.模块的俩种句式
-
模块导入式句式之import,import py文件的名称
会产生执行文件的名称空间,产生被导入文件的名称空间并运行该文件内所有的代码,存储所有的名字,在执行文件中会获取一个模块的名字 通过该名字点的方式就可以使用到被导入文件名称空间中的名字
-
模块导入式句式之from….import….,from py文件的名称 import 名字
创建执行文件的名称空间,创建被导入文件的名称空间,执行被导入文件中的代码 将产生的名字存储到被导入文件的名称空间中,在执行文件中获取到指定的名字 指向被导入文件的名称空间
5.两种句式的优缺点
-
模块导入式句式之import,import py文件的名称
优点:通过md点的方式可以使用到模块内所有的名字 并且不会冲突
缺点:md什么都可以点 有时候并不想让所有的名字都能被使用
-
模块导入式句式之from….import….,from py文件的名称 import 名字
优点:指名道姓的使用指定的名字 并且不需要加模块名前缀
缺点:名字及其容易产生冲突(绑定关系被修改)
6.导入方式中细小知识点
- 起别名:多个模块文件名相同,原有的模块文件名称
- 导入多个名字:多个模块功能相似才能适应 不相似尽量分开导入,出自一个模块文件的时候,导入名字的时候可以使用逗号隔开
- 全导入:需要使用模块名称空间中很多名字 并且只能使用from…import句式,from md import * # 表示所有,针对号的导入还可以控制名字的数量,在模块文件中可以使用
__
all__
= [字符串的名字]控制*能够获取的名字
7.循环导入问题
-
如何理解循环导入:循环导入就是两个文件彼此导彼此
-
循环导入容易出现报错现象:使用彼此的名字可能是在没有准备好的情况下就使用了
-
如何解决循环导入保存现象:彼此在使用彼此名字之前 先准备好
ps:循环导入将来尽量避免出现!!! 如果真的避免不了 就想办法让所有的名字在使用之前提前准备好
8.判断文件类型
-
所有文件中都会自带一个
__
name__
内置名 -
当py文件是执行文件的时候
__
name__
的结果是__
main__
-
当py文件是被导入文件的时候
__
name__
的结果是模块名(文件名) -
__
name__
主要用于开发模块的作者测试自己的代码使用if
__
name__
==__
main__
: 当文件是执行文件的时候才会执行if的子代码
9.模块查找顺序
内存—>内置—>sys.path中查找(程序系统环境变量)
- 导入一个文件,然后在导入过程中删除该文件 发现还可以使用
- 创建一个跟内置模块名相同的文件名
- 导入模块的时候一定要知道谁是执行文件,所有的路径都是参照执行文件来的
通用的方式:sys.path.append(目标文件所在的路径)
利用from…import句式:起始位置一定是执行文件所在的路径,from xxx import mdd
八、绝对导入与相对导入
1.绝对导入
其实就是以执行文件所在的sys.path为起始路径 往下一层层查找,from ccc.ddd.eee import b
由于pycharm会自动将项目根目录添加到sys.path中所以查找模块肯定不报错的方法就是永远从根路径往下一层层找
如果不是用pycharm运行 则需要将项目跟目录添加到sys.path
2.相对导入
相对导入可以不参考执行文件所在的路径 直接以当前模块文件路径为准,只能在模块文件中使用,不能在执行文件中使用,相对导入在项目比较复杂的情况下,可能会出错
.在路径中意思是当前路径,..在路径中意思是上一层路径,../..在路径中意思是上上一层路径
九、包的概念
1.如何理解包
内部含有__
init__
文件夹,就是包
针对python3解释器 其实文件夹里面有没有__init__.py已经无所谓了 都是包
但是针对Python2解释器 文件夹下面必须要有__init__.py才能被当做包
2.包的作用
内部存放多个py文件(模块文件) 仅仅是为了更加方便的管理模块文件
3.具体使用
import 包名
导入包名其实导入的是里面的__
init__
.py文件
其实也可以跨过__
init__
.py直接导入包里面的模块文件
4.编程思想的转变
小白阶段—>函数阶段—>模块阶段
5.软件开发目录规范
根据我们的需求,高效的管理资源,分模块文件多了之后还需要有文件夹
bin文件夹:用于存储程序的启动文件
conf文件夹:用于存储程序的配置文件
core文件夹:用于存储程序的核心逻辑,程序的功能
lib文件夹:用于存储程序的公共功能
db文件夹:用于存储程序的数据文件
log文件夹:用于存储日志文件
interface文件夹:用于存储一些接口文件
readme文本文件:类似于说明书
requirements.txt文件:用于存储程序所需的第三方模块名称和版本
十、模块
1.collections模块
namedtuple(具名元组)、deque(双端列表)、orderdict(有序字典)、defaultdict(默认值字典)、counter(计数器)
2.time模块
时间戳 time.time()、结构化时间 time.gmtime()、格式化时间 time.strftime()
struct_time通过 strftime 转变为Format string
Format string通过 strptime 转变为struct_time
struct_time通过 mktime 转变为Timestamp
Timestamp通过 localtime gmtime 转变为struct_time
3.datetime模块
方法 | 作用 |
---|---|
datetime.datetime.today() | 表示的是当前的时间 年月日时分秒 秒数精确到了后6位 |
datetime.date.today() | 表示的是当前的时间 年月日 |
datetime.date.today() | 时间差值,可以对时间进行换算,有以下参数 如果没有的话可以通过已有的进行换算 |
datetime.datetime.now()(不常用) | 表示的是当前时间 |
通过点的方式只取年或者月或者日等内置方法 | res.day、res.year、res.month |
4.os模块
方法 | 作用 |
---|---|
os.mkdir | 生成单级目录,如果目录存在的话就会报错,提示该文件夹已经存在不能再次创建 |
os.makedirs() | 创建多级目录 也可以创建单级目录 |
os.rmdir() | 可删除单级目录,但是这个目录下面什么都没有才可以被删除,也不可以删除多级空目录 |
os.removedirs() | 对有数据的目录不可以进行删除,在多级目录的情况下删除的时候是从最底下的开始,然后一层一层向上检查,如果到了那层有数据的时候,就不会删除了,没有的话就一层一层的进行删除 |
os.listdir() | 列出当前目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印,可以进行指定目录查看目录下面所有文件和子目录包括隐藏文件,并以列表方式打印 |
os.rename() | 对文件进行修改名字 |
os.remove() | 删除文件 |
os.getcwd() | 获取当前工作路径,绝对路径 |
os.chdir() | 切换路径 |
os.path.dirname(__ file__ )(支持嵌套) |
获取的是当前文件的绝对路径 |
os.path.exists() | 前者判断路径是否存在 可以是文件可以是目录 |
os.path.isdir() | 只适用于路径是否为文件夹 |
os.path.isfile() | 只适用于路径是否文件 |
os.path.join(path1[, path2[, …]]) | 将多个路径拼接后返回,join会自动识别当前在什么系统下操作的,然后给予对应的分隔符 |
os.path.getsize(path) | 获取文件大小,以bytes为单位 |
5.sys模块
方法 | 作用 |
---|---|
sys.path | 当前执行文件所在的系统变量,结果是列表 |
sys.version(了解) | |
sys.platform(了解) | |
sys.argv | 命令行参数List,第一个元素程序本身的路径 |
6.json模块
-
json模块的介绍:json模块也称之为序列化模块,是不同编程语言之间数据交互必备的模块,不同编程语言之间数据类型存在差异,无法直接交互,json模块相当于是一个中间人,作为不同的编程语言之间数据类型先来到json这里进行转为为对方可是识别的数据类型然后再交给它。
-
json格式的数据应该是什么:由于数据基于网络传输肯定是二进制,那么在python中只有字符串可以调用encode方法转成二进制数据,所以json格式的数据也是字符串
-
json格式的数据的特征是:首先肯定是一个字符串 其次引号是标志性的双引号
-
dumps() — 将其他数据类型转换成json格式字符串,loads() — 将json格式字符串转化成对应的数据类型,dump() — 将其他数据数据以json格式字符串写入文件,load() — 将文件中json格式字符串读取出来并转换成对应的数据类型
-
实现的需求是:不需要以拼接为字符串的形式去存储数据,用的时候又得需要进行切割,使用json模块后,可以直接存储数据,然后使用的时候直接拿出来.get就可以使用
7.jason模块实战
涉及到用户数据的存储 可以单用户单文件
jason.json
kevin.json
oscar.json
import json
import os
# 3.拼接用户名文件对应的绝对路径,用来打开文件,先把路径存一下
base_dir = r'D:\pythonProject\day24\db'
# 1.获取用户的输入
username = input('username:').strip()
# 4.获取路径下面所有的文件名,这里获取到的是用户的用户名
username_list = os.listdir(base_dir)
# 2.判断用户名是否存在
if username in username_list:
# 5.拼接文件的路径,某一个文件的完整路径
file_path = os.path.join(base_dir, username)
# 6.打开文件读取文件
with open(file_path, 'r', encoding='utf8') as f:
data = json.load(f)
print(data, type(data))
# print(os.listdir(r'D:\pythonProject\day24\db'))
# 专门放置一个文件夹用来存放用户的数据
# base_dir = os.path.dirname(__file__)
# db_path = os.path.join(base_dir,'db')
# 判断路径在不在 如果路径不存在就会创建
# if not os.path.exists(db_path):
# os.mkdir(db_path)
# username = input('username>>>:').strip()
# password = input('password>>>:').strip()
# user_dict = {'username': username,
# 'password': password,
# 'balance': 15000,
# 'shop_car':[]
# }
# 将名字拼接起来,相当于在db下存储文件,join是用来拼接文件路径的
# file_path = os.path.join(db_path, '%s'%username)
# 不要文件的后缀会变得更简单,用listdir的时候获取到的就是数据名,判断用户名是否存在的时候,如果有的话将绝对路径拼出来,就可以拿到用户的数据了
# file_path = os.path.join(db_path, '%s.json'%username)
# with open(file_path,'w',encoding='utf8') as f:
# json.dump(user_dict, f)