# 第七章
## 01 函数的多返回值
函数有多个返回值,如何写代码?
按照返回值的顺序,写对应顺序的变量依次接收,变量之间用逗号隔开,支持return不同的返回值类型
eg.
```
def test():
return 1,True,"hello"
x,y,z= test()
print(x)
print(y)
print(z)
print(type(test()))
```
运行结果:
```
1
True
hello
<class 'tuple'>
```
## 02 函数的多种传参方式
①位置参数:调用函数时,根据函数定义的参数位置传递参数
传递的参数顺序和定义参数的顺序和个数必须一致
②关键字参数:通过键—值队的形式传递参数
不需要顺序一致
如果有位置参数时,位置参数必须在关键字参数前面
eg.
```
def test(name,age,sex):
print(f"你的姓名是:{name},你的年龄是{age},你的性别是{sex}")
x = test("小红",sex = "女",age = 10)
```
运行结果:`你的姓名是:小红,你的年龄是10,你的性别是女`
③缺省参数(默认参数)
为参数提供默认值,调用函数时,可不传改参数的默认值,所有位置参数必须出现在默认参数前,包括函数的定义和调用
eg.
```
def test(name,age,sex="女"):
print(f"你的姓名是:{name},你的年龄是{age},你的性别是{sex}")
x = test("小红",age = 10)
```
运行结果:`你的姓名是:小红,你的年龄是10,你的性别是女`
④不定长参数(可变参数)
用于不确定调用的时候会传递多少的参数
位置传递的不定长 传进的所有变量都会被args变量收集,它会根据传进参数的位置合并成一个元组,args就是元组类型
eg.
```
def user_info(*args):
print(args)
user_info("Tom")
user_info("Tom",18)
运行结果:('Tom',)
('Tom', 18)
```
关键字传递的不定长 参数是键=值的情况下,所有的键=值都会被kwarg接收,并组成字典
eg.
```
def user_info(**kwarg):
print(kwarg)
print(type(kwarg))
user_info(name = "Tom",age = 20,sex = "男")
user_info(name = "Tom",age = 20)
```
运行结果:
```
{'name': 'Tom', 'age': 20, 'sex': '男'}
<class 'dict'>
{'name': 'Tom', 'age': 20}
<class 'dict'>
```
## 03 函数作为数据传入参数
传入数据:数据不确定,执行逻辑确定
传入函数:数据确定,执行逻辑不确定,传入计算逻辑
eg.
```
def test_fun(compete):
result = compete(1,2)
print(result)
print(type(compete))
def compete(x,y):
return x + y
test_fun(compete)
```
运行结果:
```
3
<class 'function'>
```
## 04 lambda匿名函数
def 关键字,可以定义带有名称的函数
lambda 关键字,可以定义匿名函数(无名称)
有名称的函数,可以基于名称重复使用,无名称的函数,只能临时使用一次
语法:`lambla 传入参数: 函数体(一行代码)`
传入参数是形式参数
函数体里只能写一行代码!
eg.
```
def test_fun(compete):
result = compete(1,2)
print(result)
print(type(compete))
test_fun(lambda x,y:x+y)
```
运行结果:
```
3
<class 'function'>
```
# 第八章
## 01 文件编码的概念
编码:将内容翻译成二进制,将二进制翻译回可识别的内容
最常用:UTF—8
## 02 文件的读取操作
文件:视频文件,文本文件,音频文件,图像文件,可执行文件等
操作:打开,关闭,读,写
①打开文件
语法:`open(name,mode,encoding)`
`name` --->打开文件名的字符串(可包含文件的具体路径)
`mode` --->设置打开文件的模式(只读,写,追加)
`encoding` --->编码格式(推荐UTF-8)
`r` 只读模式,指针放在文件的开头,默认模式
`w` 文件存在,从头开始编辑,原有内容被删除,文件不存在,就创建新文件
`a` 追加,文件存在,从结尾开始写,文件不存在,就创建新文件
eg.
```
f = open("D:/csdn链接.txt",'r',encoding="UTF-8")
print(type(f))
```
运行结果:`<class '_io.TextIOWrapper'>`
②读文件
语法1:`read(num)`
num --->要从文件中读取的数据的长度,没有num就读取全部数据
多次调用read()会从上一次读的末尾开始读
eg.
```
f = open("D:/csdn链接.txt",'r',encoding="UTF-8")
print(f"读取10个字节的结果:{f.read(10)}")
```
运行结果:读取10个字节的结果:`http://t.c`
语法2:`readlines()`
按照行的方式一次性读取内容,返回列表,每一行作为一个元素
eg.
```
f = open("D:/csdn链接.txt",'r',encoding="UTF-8")
print(f"读取全部的结果:{f.readlines()},f.readlines的数据类型是:{type(f.readlines())}")
```
运行结果:读取全部的结果:`['sdn.cn/EqESz\n', 'http://t.csdn.cn/1F6Rp(之后)\n', 'http://t.csdn.cn/zgBMG'],f.readlines的数据类型是:<class 'list'>`
语法3:`readline()`
一次读一行
eg.
```
f = open("D:/csdn链接.txt",'r',encoding="UTF-8")
print(f"读取全部的结果:{f.readline()},f.readline的数据类型是:{type(f.readline())}")
```
运行结果:
```
读取全部的结果:http://t.csdn.cn/EqESz
,f.readline的数据类型是:<class 'str'>
```
④文件内容的遍历
eg.
```
f = open("D:/csdn链接.txt",'r',encoding="UTF-8")
for x in f:
print(x)
```
运行结果:
```
http://t.csdn.cn/EqESz
http://t.csdn.cn/1F6Rp(之后)
http://t.csdn.cn/zgBMG
```
⑤文件的关闭
语法1:`文件.close()`
eg.
```
f = open("D:/csdn链接.txt",'r',encoding="UTF-8")
f.close()
```
语法2:`with open(name,mode,encoding) as 文件名:`
自动关闭文件
eg.
```
with open("D:/csdn链接.txt",'r',encoding="UTF-8") as f:
for x in f :
print(x)
```
运行结果:
```
http://t.csdn.cn/EqESz
http://t.csdn.cn/1F6Rp(之后)
http://t.csdn.cn/zgBMG
```
## 03 文件的写入
语法:`write("内容")` --->文件的写入
`flush()` --->文件的刷新
直接调用write(),内容并未直接写入文件,而是积攒在程序的内存中,称之为缓冲区
当调用flush(),内容才被真正写入文件
这样避免频繁操作硬盘,导致效率下降(攒一推,一次性写入硬盘)
eg.
```
f = open("D:/test.txt","w",encoding="UTF-8")
f.write("hello world")
```
```
#程序休眠,说明已完成文件的创建
#调用flush(),在硬盘里写入内容
#f.flush()
#f.close()内置flush()功能
f.close()
#文件内容:hello world
f = open("D:/test.txt","w",encoding="UTF-8")
# 覆盖写入
f.write("hello python")
f.close()
#文件内容:hello python
f = open("D:/test.txt","a",encoding="UTF-8")
```
```
# 覆盖写入
f.write("\nGood night")
f.close()
文件内容:hello python
Good night
```
# 第九章
## 01 了解异常
程序运行过程中出现了错误,bug-->异常,错误
## 02 捕获异常
捕获异常:提前假设某处出现异常,提前做好准备
语法1:
```
try:
可能发生错误的代码
except:
如果出现异常,执行的代码
```
eg.
```
try:
f = open("D:/abcd.txt","r",encoding="UTF-8")
except:
print("出错了,文件不存在,建议将只读模式改为写入模式,再打开")
```
运行结果:`出错了,文件不存在,建议将只读模式改为写入模式,再打开`
语法2:捕获指定的异常
```
try:
可能发生错误的代码
except 异常类型 as e:
如果出现异常,执行的代码
```
eg.
```
try:
set(name)
except NameError as e:
print("出错了,变量未创建")
print(e)
```
运行结果:
```
出错了,变量未创建
name 'name' is not defined
```
e --->异常的对象
语法3:捕获多个异常
```
try:
可能发生错误的代码
except (异常类型1,异常类型2) as e:
如果出现异常,执行的代码
```
用元组把异常包起来
eg.
```
try:
1/0
except (NameError,ZeroDivisionError) as e:
print("出错了,出现了变量未定义或者除0的异常")
print(e)
```
运行结果:
```
出错了,出现了变量未定义或者除0的异常
division by zero
```
语法4:捕获所有的异常
```
try:
可能发生错误的代码
except Exception as 别名:
如果出现异常,执行的代码
```
eg.
```
try:
f = open("D:/abcd.txt", "r", encoding="UTF-8")
except Exception as e:
print("出错了,出现了异常")
print(e)
```
运行结果:
```
出错了,出现了异常
[Errno 2] No such file or directory: 'D:/abcd.txt'
```
## 03 异常的传递
异常具有传递性,会向上一层一层抛出异常,到捕获为止或直接抛出异常
eg.
```
def func1():
print("function1 开始工作")
# 除0异常
print(1/0)
print("function1 结束工作")
def func2():
print("function2 开始工作")
func1()
print("function2 结束工作")
def main():
func2()
main()
```
运行结果:
```
Traceback (most recent call last):
File "D:\pythondemo\test2.py", line 270, in <module>
main()
File "D:\pythondemo\test2.py", line 269, in main
func2()
File "D:\pythondemo\test2.py", line 266, in func2
func1()
File "D:\pythondemo\test2.py", line 262, in func1
print(1/0)
ZeroDivisionError: division by zero
出错了,出现了异常
[Errno 2] No such file or directory: 'D:/abcd.txt'
function2 开始工作
function1 开始工作
```
修改代码如下:
```
def func1():
print("function1 开始工作")
# 除0异常
print(1/0)
print("function1 结束工作")
def func2():
print("function2 开始工作")
func1()
print("function2 结束工作")
def main():
try:
func2()
except Exception as e:
print(f"出现异常了,出现的异常是{e}")
main()
```
运行结果:
```
function2 开始工作
function1 开始工作
出现异常了,出现的异常是division by zero
```
## 04 模块的概念及导入
Python模块(Module),是一个Python文件,以.py结尾,模块能定义函数,类和变量,模块里也能包含可执行的代码
Python中有很多模块,能帮助我们实现不同的功能,一个模块~=一个工具包
语法:
```
[from 模块名] import[模块名|类|变量|函数|*] [as 别名]
```
eg.
```
import time
time.sleep(300)
```
. --->表示层级关系,通过.拿模块里的函数等
eg.`from 模块名 import 功能名`
```
from time import sleep
sleep(1)
```
eg.`from 模块名 import *`
```
from time import *
sleep(1)
```
eg. `from 模块名 import 功能名 as 别名`
```
from time import sleep as sl
sl(1)
```
eg.`import 模块名 as 别名`
```
import time as t
t.sleep(3)
```
## 05 自定义模块
自定义模块,实现模块的个性化
语法:`import 模块名 --->python文件的名字,注意标识符符合命名规则`
eg.
自定义模块my_module:
```
def test(x,y):
return x + y
```
导入模块并使用:
```
import my_module
x = my_module.test(1,3)
print(x)
```
eg.导入不同模块的同名功能,前面的模块功能会被后面模块的功能覆盖
再建一个模块my_mobule1:
```
def test(x,y):
return x - y
```
调用my_module,my_mobule1的test:
```
from my_module import test
from my_module1 import test
print(test(1,2))
```
运行结果:`-1`
问题:在自定义模块里做测试,但不想被导入的时候输出测试结果
解决:使用`if __name__ == '__main__':`
```
def test(x,y):
return x + y
if __name__ == '__main__':
print(test(1,2))
```
这样但不想被导入的时候不会有模块里的测试结果
问题:调用*时调用特定功能
解决:`__all__ = [功能名]`
eg.
```
my_module:
def test_a(x,y):
print(x + y)
def test_b(x,y):
return x + y
__all__ = ["test_a"]
```
调用my_module:
```
from my_module import *
test_a(1,2)
```
## 06 自定义Python包
"""
python包:文件夹,包含了一个__init__.py文件,可包含多个模块文件
包的本质仍是模块
语法1:import 包名.模块名
自定义包:my_package
里有模块module_01:
def test():
print("我是包下模块一的代码")
里有模块module_02:
def test():
print("我是包下模块二的代码")
def test_info():
print("我是我是包下模块二的方法二")
导包调用
import my_package.module_01
import my_package.module_02
my_package.module_01.test()
my_package.module_02.test_info()
运行结果:我是包下模块一的代码
我是我是包下模块二的方法二
语法2:from 包名 import 模块名
eg.from my_package import module_01
from my_package import module_02
module_01.test()
module_02.test_info()
运行结果:我是包下模块一的代码
我是我是包下模块二的方法二
语法3:from 包名.模块名 import 函数
eg.
from my_package.module_01 import test
from my_package.module_02 import test_info
test()
test_info()
运行结果:我是包下模块一的代码
我是我是包下模块二的方法二
使用import * 时限定模块
语法:__all__ = ["模块名"]
import * 时则只会用到上面语法中的模块
"""
## 07 第三方包
命令提示符
pip install 包名称
# 第十章
## 01 JSON数据格式的转换
JSON本质上是一个带有特定格式的字符串,是一种在各个编程语言中流通的数据格式,负责不同编程语言的数据交互
Python数据和JSON数据的转化
eg.
```
import json
data = [{"小王":60},{"小红":90},{"小绿":80}]
```
① python转json
列表转
```
json_str = json.dumps(data,ensure_ascii=False)
print(json_str)
print(type(json_str))
```
运行结果:
```
[{"小王": 60}, {"小红": 90}, {"小绿": 80}]
<class 'str'>
```
字典转
```
import json
data = {"小王":60,"小红":90,"小绿":80}
```
② python转json
```
json_str = json.dumps(data,ensure_ascii=False)
print(json_str)
print(type(json_str))
```
运行结果:
```
[{"小王": 60}, {"小红": 90}, {"小绿": 80}]
<class 'str'>
```
③ json转python
转列表
```
import json
data1 = '[{"小王":60},{"小红":90},{"小绿":80}]'
python_l = json.loads(data1)
print(python_l)
print(type(python_l))
```
运行结果:
```
[{'小王': 60}, {'小红': 90}, {'小绿': 80}]
<class 'list'>
```
转字典
```
import json
data = '{"小王":60,"小红":90,"小绿":80}'
python_l = json.loads(data)
print(python_l)
print(type(python_l))
```
运行结果:
```
{'小王': 60, '小红': 90, '小绿': 80}
<class 'dict'>
```
## 02 pyecharts
下载 pip install pyecharts
官方画廊 gallery.pyecharts.org
## 03 pyecharts入门
①折线图
```
# 导入Line功能构建折线对象
from pyecharts.charts import Line
# 得到折线对象
line = Line()
# 添加x轴
line.add_xaxis(["中国","美国","英国"])
# 添加y轴
line.add_yaxis("GDP",[30,20,10])
# 生成图表
line.render()
全局配置选项 -->set_global_opts方法
TitleOpts:标题配置项
ToolboxOpts:工具箱配置项
LegendOpts:图例配置项
VisualMapOpts:视觉映射配置项
DataZoomOpts:区域缩放配置项
"""
# 导入Line功能构建折线对象
from pyecharts.charts import Line
# 导配置选项对应的包
from pyecharts.options import TitleOpts,LegendOpts,ToolboxOpts,VisualMapOpts
# 得到折线对象
line = Line()
# 添加x轴
line.add_xaxis(["中国","美国","英国"])
# 添加y轴
line.add_yaxis("GDP",[30,20,10])
# 设置全局配置选项
line.set_global_opts(
# 居中,底部
title_opts = TitleOpts(title="GDP展示",pos_left="center",pos_bottom="1%"),
legend_opts = LegendOpts(is_show = True),
toolbox_opts=ToolboxOpts(is_show=True),
visualmap_opts = VisualMapOpts(is_show = True),
)
# 生成图表
line.render()
```
![GDP展示图表](https://img-blog.csdnimg.cn/b1991033b2604ddbb2b9fde045e7512f.jpeg#pic_center)
## 04 数据的准备
```
f_us = open("D:/美国.txt",'r',encoding="UTF-8")
us_data = f_us.read()
# 去掉开头不符合规范的数据
#jsonp_1629344292311_69436
us_data = us_data.replace("jsonp_1629344292311_69436(","")
# 去掉结尾不符合规范的数据
us_data = us_data[:-2]
# json转python
us_dict = json.loads(us_data)
# 取元素
trend_data = us_dict['data'][0]['trend']
x_data = trend_data['updateDate'][:314]
print(x_data)
y_data = trend_data['list'][0]['data'][:314]
print(y_data)
```
## 05 折线图生成
```
import json
from pyecharts.charts import Line
from pyecharts.options import TitleOpts, LabelOpts
# 处理数据
f_us = open("D:/美国.txt", "r", encoding="UTF-8")
us_data = f_us.read() # 美国的全部内容
f_jp = open("D:/日本.txt", "r", encoding="UTF-8")
jp_data = f_jp.read() # 日本的全部内容
f_in = open("D:/印度.txt", "r", encoding="UTF-8")
in_data = f_in.read() # 印度的全部内容
# 去掉不合JSON规范的开头
us_data = us_data.replace("jsonp_1629344292311_69436(", "")
jp_data = jp_data.replace("jsonp_1629350871167_29498(", "")
in_data = in_data.replace("jsonp_1629350745930_63180(", "")
# 去掉不合JSON规范的结尾
us_data = us_data[:-2]
jp_data = jp_data[:-2]
in_data = in_data[:-2]
# JSON转Python字典
us_dict = json.loads(us_data)
jp_dict = json.loads(jp_data)
in_dict = json.loads(in_data)
# 获取trend key
us_trend_data = us_dict['data'][0]['trend']
jp_trend_data = jp_dict['data'][0]['trend']
in_trend_data = in_dict['data'][0]['trend']
# 获取日期数据,用于x轴,取2020年(到314下标结束)
us_x_data = us_trend_data['updateDate'][:314]
jp_x_data = jp_trend_data['updateDate'][:314]
in_x_data = in_trend_data['updateDate'][:314]
# 获取确认数据,用于y轴,取2020年(到314下标结束)
us_y_data = us_trend_data['list'][0]['data'][:314]
jp_y_data = jp_trend_data['list'][0]['data'][:314]
in_y_data = in_trend_data['list'][0]['data'][:314]
# 生成图表
line = Line() # 构建折线图对象
# 添加x轴数据
line.add_xaxis(us_x_data) # x轴是公用的,所以使用一个国家的数据即可
# 添加y轴数据
line.add_yaxis("美国确诊人数", us_y_data, label_opts=LabelOpts(is_show=False)) # 添加美国的y轴数据
line.add_yaxis("日本确诊人数", jp_y_data, label_opts=LabelOpts(is_show=False)) # 添加日本的y轴数据
line.add_yaxis("印度确诊人数", in_y_data, label_opts=LabelOpts(is_show=False)) # 添加印度的y轴数据
# 设置全局选项
line.set_global_opts(
# 标题设置
title_opts=TitleOpts(title="2020年美日印三国确诊人数对比折线图", pos_left="center", pos_bottom="1%")
)
# 调用render方法,生成图表
line.render()
# 关闭文件对象
f_us.close()
f_jp.close()
f_in.close()
```
![确诊人数比较图](https://img-blog.csdnimg.cn/598723958b9e4794a502e1d01f37f5a5.jpeg#pic_center)
# 第十一章
## 01 类的初步认识
类-->定义表
对象 -->打印表
赋值 -->填表
语法:
```
class 类名:
属性 = xx
属性 = xx
属性 = xx
属性 = xx
```
eg.
```
# 创建类
class Student:
name = None
age = None
sex = None
place = None
# 创建对象
student1 = Student()
# 赋值
student1.age = 12
student1.sex = "女"
student1.place = "南京"
student1.name = "小爱"
# 打印
print(student1.age)
print(student1.sex)
print(student1.name)
print(student1.place)
```
运行结果:
```
12
女
小爱
南京
```
# 02 类的成员方法
语法:
```
class 类名:
属性
属性
方法
方法
```
创建对象 `对象名 = 类名()`
属性 --->成员变量
方法 --->成员方法
定义成员方法
```
def 方法名(self,形参,形参):
方法体
```
self表示类对象自身的意思
在方法内部想要访问成员变量,必须使用self
传入参数时,可以当self不存在
eg.
```
class Student:
name = None
def say_hi(self,msg):
print(f"你们好,我是{self.name},{msg}")
student = Student()
student.name = "小爱"
student.say_hi("请大家多多关照")
```
运行结果:`你们好,我是小爱,请大家多多关照`
## 03 类和对象
面向对象:设计类,基于类,构建对象做具体的工作
eg.
```
class Clock:
id = None
price= None
def ring(self):
import winsound
winsound.Beep(2000,3000)
clock1 = Clock()
clock1.price = 100
clock1.id = "001200"
print(f"{clock1.id}闹钟的价格是{clock1.price}")
clock1.ring()
clock2 = Clock()
clock2.price = 10.2
clock2.id = "001201"
print(f"{clock2.id}闹钟的价格是{clock2.price}")
```
运行结果:
```
001200闹钟的价格是100
001201闹钟的价格是10.2
```
## 04 构造方法
使用`__init__()`方法,称之为构造方法
构建类对象的时候会自动执行,会将传入的参数自动传递给`__init__`方法使用
eg.
```
class Student:
# name = None
# tel = None
# age = None
def __init__(self,name,tel,age):
# 有定义及赋值的功能
self.name = name
self.tel = tel
self.age = age
print("Student类的构造方法")
stu = Student("小爱","123456789","12")
print(stu.age)
print(stu.tel)
print(stu.name)
```
运行结果:
```
Student类的构造方法
12
123456789
小爱
```
## 05 魔术方法
Python类的内置方法有不同的功能,称之为魔术方法
字符串方法:`__str__`
比较方法:
```
__lt__
,__le__, __eq__
```
eg.
```
class Student:
# name = None
# tel = None
# age = None
def __init__(self,name,tel,age):
# 有定义及赋值的功能
self.name = name
self.tel = tel
self.age = age
# 字符串方法
def __str__(self):
return f"学生的名字是:{self.name},学生的电话是:{self.tel},学生的年龄是{self.age}"
# 比较方法(<,>)
def __lt__(self, other):
return self.age < other.age
# 比较方法(<=,>=)
def __le__(self, other):
return self.age <= other.age
# 等于方法(==)
def __eq__(self, other):
return self.age == other.age
stu = Student("小爱","123456789","12")
stu1 = Student("大林","123450000","22")
print(stu)
print(stu1)
print(stu<stu1)
print(stu>=stu1)
print(stu==stu1)
```
运行结果:
```
学生的名字是:小爱,学生的电话是:123456789,学生的年龄是12
学生的名字是:大林,学生的电话是:123450000,学生的年龄是22
True
False
False
```
## 06 封装
面向对象编程的三大特性:封装,继承,多态
封装:将现实中的事物描述为程序中的类,将现实事物的属性,行为描述为类的成员变量,成员方法
现实事物中有私有的属性和行为,类中也要有对应私有的成员变量,成员方法
语法:`__成员变量名,__成员方法名`
私有成员变量,成员方法不能被类对象直接调用,但类的其他成员可以使用私有成员变量和私有方法
eg.
```
class Phone:
# 运行电压
__current_v = 0.5
# 以单核模式运行
def __keep_single_core(self):
print("以单核模式运行")
def call_5g(self):
if self.__current_v >= 1:
print("电压已开启")
else:
self.__keep_single_core()
print("电量不足,改为单核模式省电")
phone = Phone()
phone.call_5g()
```
运行结果:
```
以单核模式运行
电量不足,改为单核模式省电
```
## 07 继承的基本语法
语法:
```
class 类名(父类名):
内容体
```