一、基础语法
1.字变量
字变量:在代码中,被写下来的固定的值
字符串:python中用双引号包裹起来的都是字符串
"""
本代码演示了
-各类字变量的写法
-通过print语句输出各类字变量
"""
# 写一个整数字变量
666
# 写一个浮点数字变量
13.14
# 写一个字符串字变量
"你不困我困"
print(666)
print(13.14)
print("你不困我困")
2. 注释
#单行注释
“”“注释内容”“” 多行注释
3. 变量
在程序运行时,能存储计算结果或能表示值的抽象概念,用来积记录数据
4.数据类型
-
在print语句中,直接输出类型信息
print(type(666))
-
用变量存储type()的结果
string_type=type("你不困我困")
-
可以查看字变量和变量的类型
-
变量无类型,但是它存储的数据有
# 方式1:使用print语句直接输出类型信息
print(type(666))
# 方式2:使用变量存储type()语句的结果
string_type = "你不困我困"
print(type(string_type))
# 方式3:使用type()语句,查看变量中存储的数据类型信息
name = "你不困我困"
print(type(name))
5. 数据类型转换
- 数据类型转化,是以后经常需要使用的功能
- 从文件中读取的数字,默认是字符串,需要转换为数字类型
- input()语句,默认结果是字符串,若需要数字也需要转换
- 将数字转换为字符串用以写出到外部系统
语句(函数) | 说明 |
---|---|
int(x) | 将x转化为一个整数 |
float(x) | 将x转换为一个浮点数 |
str(x) | 将x转换为字符串 |
5. 标识符
-
在python中,可以给很多东西取标识符
- 变量的名字
- 方法的名字
- 类的名字
-
是用户在编程的时候所使用的一系列名字,用于给变量、类、方法等命名
-
Python中,标识符命名的规则
- 内容限定
- 标识符命名中只允许出现:英文、中文、数字、下划线_
- 不推荐使用中文
- 数字不可以作为开头
- 大小写敏感
- 大小写是能完全区分的
- 不可使用关键字
- 内容限定
-
变量的命名
- 明了
- 下划线命名法
- 全部小写
# 将数字类型转换为字符串
num_str = str(11)
print(type(num_str), num_str)
float_str = str(11.345)
print(type(float_str), float_str)
# 将字符串转换为数字
num = int("11")
print(type(num), num)
num2 = float("11.345")
print(type(num2), num2)
# 整数转浮点数
float_num = float(11)
print(type(float_num), float_num)
# 浮点数转整数 会丢失精度
int_num = int(11.34)
print(type(int_num), int_num)
6. 运算符
# 算术运算符
print("1+1= ", 1+1)
print("1-1= ", 1-1)
print("1*2= ", 1*1)
print("2/1= ", 2/1)
print("21//2= ", 21//2) # 整除
print("2**2 = ", 2**2)
# 赋值运算符
num = 1+2*3
print("num=", num)
# 复合赋值运算符
num2 = 1
print("num2 =", num2)
num2 += 1
print("num2+1 =", num2)
7. 字符串扩展
-
字符串的三种定义方式
1.单引号定义法:name='你不困我困' 2.双引号定义法:name="你不困我困" 3.三引号定义法:name="""你不困我困""" # 不用变量接收就是注释
- 字符串的引号嵌套:
- 单引号定义法:可以内含双引号
- 双引号定义法:可以内含单引号
- 可以使用转义字符 \ 将引号接触效用,变成普通字符
- 字符串的引号嵌套:
-
字符串拼接
# 字符串字变量之间的拼接 print("1.你不困" + "我困") # 字符串字变量和字符串变量的拼接,必须是两个字符串间拼接 name = "我困" tel = "111111" print("2.你不困" + name + ",我的电话是:" + tel)
-
字符串格式化
# 通过占位的形式,完成拼接 name = "翻斗花园" message = "3.胡图图住在:%s" % name print(message) # 通过占位的形式,完成数字和字符串的拼接 class_num = 57 avg_salary = 9989 message = "4.胡英俊的工号是%d,工资是%d" % (class_num, avg_salary) print(message)
-
字符串格式化的精度控制
-
可以使用辅助符号m.n 来控制数据的宽度和精度
m,控制宽度,要求数字(很少使用),设置的宽度小于数字自生,不生效
.n,控制小数点精度,要求是数字,会进行小数的四舍五入
num1 = 11 num2 = 11.2345678 print("数字11宽度限制5,结果是:%5d" % num1) print("数字11宽度限制1,结果是:%1d" % num1) print("数字11.2345678宽度限制7,小数精度2,结果是:%7.2f" % num2) print("数字11.2345678小数精度2,结果是:%.2f" % num2)
-
-
字符串格式化2
f"{变量}…"
- 不在意类型
- 不会做精度控制
name = "翻斗花园" address = 112 mam = "张小丽" print(f"胡图图住在{name}{address}室,妈妈是{mam}")
-
对表达式进行格式化
8. 数据输入
- input语句的功能是获取键盘输入的数据
- 可以使用,input(提示信息),用以在使用者输入内容之前显示提示信息
- 要注意,无论键盘输入什么类型的数据,获取的数据永远都是字符串类型
二、python判断语句
1. if语句的基本格式
if 要判断的条件:
条件成立时,要做的事
2. range()
-
range(num)
获取一个从0开始,到num结束的数字序列(不含num本身)
-
range(num1,num2)
获取一个从num1开始,到num2结束的数字序列(不包含num2本身)
-
range(num1,num2,step)
获取一个从num1开始,到num2结束的数字序列(不包含num2本身)
数字之间的步长,以step为准,默认是1
三、循环语句
1. while
# 无限次机会,每次猜不着会提示,猜中数字后会提示猜了几次
import random
num = random.randint(1, 100)
# 通过一个布尔类型的变量,做循环是否继续的标记
flag = True
# 定义一个变量,记录总共猜测了几次
count = 0
while flag:
guess_num = int(input("请输入您猜测的数字:"))
count += 1
if guess_num == num:
print("猜中了!")
# 设置flag就是循环终止的条件
flag = False
else:
if guess_num > num:
print("您猜测的数据较大!")
else:
print("您猜测的数据较小!")
print(f"您总共猜测了{count}次")
# i = 0
# while i < 10:
# print("你不困")
# i += 1
# 通过while循环,计算1累加到100的和
i = 1
sum_i = 0
while i <= 100:
sum_i += i
i += 1
print(f"1到100的累加和为:{sum_i}")
i = 1
while i <= 10:
print(f"今天是表白的第{i}天,")
j = 1
while j <= 3:
print(f"送第{j}只玫瑰")
j += 1
print("tutu I love you")
i += 1
i -= 1
print(f"坚持到第{i}天,表白成功")
i = 1
while i <= 9:
j = 1
while j <= i:
# 内层循环的print语句,不要换行
# 通过\t制表符来对齐
print(f"{j}*{i}={j*i}\t", end='')
j += 1
i += 1
# print()就是换行
print()
2. for
name = "nibukunwokun"
# 将name中的内容,挨个输出赋予x变量
# 就可以在循环体中对x进行处理
for x in name:
print(x, end='')
# for 变量 in 待处理数据集
# 同while循环不同,for循环无法定义循环条件
# 统计如下字符串有多少个u
name = "nibukunwokun"
count = 0
for x in name:
if x == "u":
count += 1
print(f"{name}中有{count}个u")
# 打印九九乘法表
# 通过外层循环控制行数
for i in range(1, 10):
# 通过内存循环控制每一行的输出
for j in range(1, i+1):
print(f"{j}*{i}={j*i}\t", end='')
# 外层循环可以通过print输出一个回车符
print()
3. range()
# for x in range(10):
# print(x, end='')
# print()
#
# for x in range(2, 5):
# print(x, end='')
# print()
#
# for x in range(2, 10, 2):
# print(x, end='')
for x in range(10):
print("送玫瑰花")
4. 循环中断
# 演示循环中断语句continue
# for i in range(1, 6):
# print("语句1")
# continue # 结束本次循环,开始下次循环
# print("语句2") # 不会执行
# 演示continue的嵌套应用
# for i in range(1,6):
# print("语句1")
# for j in range(1, 6):
# print("语句2")
# continue
# print("语句3")
# print("语句4")
# 演示循环中断语句 break
# for i in range(1, 100):
# print("语句1")
# break # 循环直接终止
# print("语句3")
# print("语句2")
# 演示break的嵌套应用
for i in range(1, 6):
print("语句1")
for j in range(1, 6):
print("语句2")
break
print("语句3")
print("语句4")
四、函数
函数:是组织好的,可重复使用的,用来实现特定功能的代码段
# 统计字符串的长度,不使用内置函数len()
str1 = "nibukun"
str2 = "wokun"
str3 = "hututu"
# count = 0
# for i in str1:
# count += 1
# print(f"字符串 {str1} 的长度是: {count}")
# 可以使用函数来优化整个过程
def my_len(data):
count = 0
for i in data:
count += 1
print(f"字符串 {data} 的长度是{count}")
my_len(str1)
my_len(str2)
my_len(str3)
为了得到一个针对特定需求,可供重复利用的代码段,提高程序的复用性,减少重复性代码,提高开发效率
1. 函数的定义
def 函数名(传入参数):
函数体
return 返回值
- 参数如不需要,可以省略
- 返回值如不需要,可以省略
- 函数必须先定义后使用
2. 函数的传入参数
传入参数的功能:在函数进行计算的时候,接受外部提供的数据
# 定义两数相加的函数,通过参数接收被计算的两个数字
def my_add(x, y):
result = x + y
print(f"{x}+{y}的计算结果是:{result}")
# 调用函数,传入被计算的两个数字
my_add(1, 2)
- 传入参数的数量是不受限制的
3. 函数返回值
-
掌握函数返回值的作用
-
掌握函数返回值的定义语法
def 函数(参数...):
函数体
return 返回值
变量 = 函数(参数)
-
函数返回字
函数在执行完成后,返回给调用者的结果
-
返回值的应用语法:
使用关键字:return 来返回结果
-
注意
函数体在遇到return后就结束了,所以写在return后的代码不会执行
-
无返回值的函数,实际上就是返回了:None这个字变量
- 在if判断上
- None等同于False
- 一般用于函数中主动返回None,配合if判断做相关处理
- 在if判断上
4. 变量在函数中的作用域
变量作用域指的是变量的作用范围(变量在哪里可以使用,在哪里不可以使用)
主要可以分为两类:局部变量和全局变量
-
局部变量:定义在函数体内部的变量,只在函数体内部生效
作用:子啊函数体内部,临时保存数据,当函数调用完成后,立刻销毁局部变量
-
全局变量:在函数体内,外都可以生效的变量
-
使用global关键字,可以将函数内部变量声明为全局变量
五、Python数据容器
1. 数据容器入门
-
什么是数据容器
一个可以容纳多份数据的数据类型,容纳的每一份数据称之为一个元素,每一个元素可以是任意类型的数据
-
数据容器根据其特点的不同,可以分为:
- 是否支持重复元素
- 是否可以修改
- 是否有序
分为5类:列表,元组,字符串,集合,字典
2. 列表(list)
# 字变量
[元素1,元素2,元素3,.....]
# 定义变量
变量名称 = [元素1,元素2,元素3,.....]
# 定义空列表
变量名称 = []
变量名称 = list
-
以[]作为标识
-
列表内每个元素用逗号隔开
-
使用下标索引,取出特定位置的数据(下标从0开始,依次递增/或者逆序,从下标-1开始)
列表除了可以
- 定义和使用下标索引获取值
还提供了一系列的功能(列表的方法)
- 插入元素
- 删除元素
- 清空列表
- 修改元素
- 统计元素个数
函数是一个封装的代码单元,可以提供特定功能,在Python中,如果将函数定义为class(类)的成员,那么函数会称之为方法
class 方法名:
函数
# Student方法
class Student:
def add(self,x,y):
return x+y
# 方法的使用
student = Student()
num = student.add(1,2)
-
查询某元素的下标
功能:查找指定元素在列表的下标,如果找不到,就会报错ValueError
列表.index(元素) # index就是列表对象(变量)内置的方法(函数)
-
修改特定位置(索引)的元素值
列表[下标] = 值 # 直接对指定下标(正向、反向下标均可)的值进行重新赋值
-
插入元素
列表.insert(下标,元素) # 在指定的下标位置,插入指定的元素
-
追加元素
列表.append(元素),将指定元素,追加到列表的尾部 # 追加单个元素 列表.extend(其他数据容器) # 将其他数据容器的内容取出,依次追加到列表尾部
-
删除元素
del列表[下标] 列表.pop(下标) # 可将删除元素进行记录
-
删除某元素在列表中的第一个匹配项
列表.remove(元素)
-
清空列表
列表.clear()
-
统计某元素在列表中的数量
列表.count(元素)
-
统计列表内,有多少元素
len(列表)
-
列表的特点
- 可以容纳多个元素
- 可以容纳不同类型的元素(混装)
- 数据是有序存储的(有下标序号)
- 允许重复数据存在
- 可以修改(增加或者删除元素)
3. list的遍历
将容器内的元素依次取出进行处理的行为,称之为遍历或者迭代
-
while循环
- 通过列标[下标]的方式取出
def list_while_func(): my_list = ["胡图图", "张小丽", "胡英俊"] """ 循环控制变量通过下标索引来控制,默认0 每一次循环将下标索引+1 循环条件:下标索引变量<列表的元素数量 """ # 定义一个变量用来标记列表的下标 index = 0 while index < len(my_list): element = my_list[index] print(f"列表的元素:{element}") index += 1 list_while_func()
-
for循环
for 临时变量 in 数据容器: 对临时变量进行处理
表示,从容器中,依次取出元素并赋值到临时变量上,在每一次的循环中,我们可以对临时变量进行处理
def list_for_func(): my_list = [1, 2, 3, 4, 5] for element in my_list: print(f"列表的元素:{element}") list_for_func()
-
while循环适用于任何想要循环的场景
-
for循环适用于,遍历数据容器的场景和简单的固定次数循环场景
4. 元组(tuple)
-
元组和列表一样,都可以封装多个,不同类型的元素在内,但是最大的不同点在于:元组一旦定义完成,就不可再被修改
# 定义元素字变量 (元素,元素....元素) # 定义元组变量 变量名称 = (元素,元素....元素) # 定义空元组 变量名称 = () 变量名称 = tuple()
-
注意:元组中只有一个数据,这个数据后面要添加括号
-
元组的相关操作
编号 方法 作用 1 index() 查找某个数据,如果数据存在返回对应的下标,否则报错 2 count() 统计某个数据在当前元组中出现的次数 3 len(元组) 统计元组内的元素个数 -
元组的元素不可以变,但是如果元组的元素包括list,可变list中的内容
5. 字符串
-
同元组一样,不可修改
-
字符串的相关操作
方法 作用 字符串.index(字符串) 查找特定字符串的下标索引值 字符串.replace(字符串1,字符串2) 将字符串中全部字符串1替换为字符串2(不是修改字符串本身,而是得到一个新字符串) 字符串.split(分隔符字符串) 按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中(字符串本身不变,而是得到了一个列表对象) 字符串.strip() 去除前后的空格 字符串.strip(字符串) 去除前后指定字符串
6. 数据容器的切点
-
序列:内容连续,有序,可使用下标索引的一类数据容器
列表,元组,字符串均可视为序列
-
切片:从一个序列中,取出一个子序列
# 从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列 # 步长为负数表示反向标记 # 对序列进行切片操作不会影响序列本身,而是得到一个新的序列 序列[起始下标:结束下标:步长]
# 对list进行切片,从1开始,4结束,步长1 my_list = [0, 1, 2, 3, 4, 5, 6] result1 = my_list[1:4:1] print(f"结果1:{result1}") # 对tuple切片,从头开始,到最后结束,步长1 my_tuple = (0, 1, 2, 3, 4, 5, 6) result2 = my_tuple[:] # 起始和结束可以默认不写表示从头到尾,步长1可以省略 print(f"结果2:{result2}") # 对str进行切片,从头开始,到最后结束,步长2 my_str = "01234567" result3 = my_str[::2] print(f"结果3:{result3}") # 对str进行切片,从头开始,到最后结束,步长-1 result4 = my_str[::-1] # 等同于将序列反转 print(f"结果4:{result4}") # 对列表进行切片,从3开始到1结束,步长-1 my_list = [0, 1, 2, 3, 4, 5, 6] result5 = my_list[3:1:-1] print(f"结果5:{result5}") # 对元组进行切片,从头开始,到最后结束,步长-2 result6 = my_tuple[::-2] print(f"结果6:{result6}")
7. 集合(set)
-
基本定义语法
# 定义集合字变量 {元素,元素......元素} # 定义集合变量 变量名称 = {元素,元素......元素} # 定义空集合 变量名称 = set()
-
集合是无序的,所以集合不支持下标索引访问,但是集合和列表一样,允许修改
-
集合的相关操作
方法 作用 集合.add(元素) 将指定元素,添加到集合内 集合.remove(元素) 将指定元素,从集合内移除 集合.pop() 从集合中随机取出一个元素 集合1.difference(集合2) 取出集合1和集合2的差集(集合1但是集合2没有的),得到一个新集合,集合1,2 不变 集合1.difference_update(集合2) 对比集合1和集合2,在集合1内,删除和集合2相同的元素,集合1被修改,集合2不变 集合1.union(集合2) 将集合1和集合2组成新集合,得到新集合,集合1,2 保持不变 len(集合) 得到一个整数,记录了集合的元素数量
8. 字典/映射(dict)
-
字典的定义
存储的是键值对
# 定义字典字变量 {key:value,key:value......key:value} # 定义字典变量 my_dict = {key:value,key:value......key:value} # 定义空字典 my_dict = {} my_dict = dict()
-
key和value可以是任意数据类型,但是key不能为字典
-
字典是可以嵌套的
-
字典的相关操作
方法 作用 dict[key] = value 字典被修改,新增了元素 dict[key] = value 字典key不可以重复,若对已经存在的key执行,相当于更新value值 dict.pop(key) 获取指定key的value,同时字典被修改,指定key的数据被删除 dict.keys() 得到字典的全部key 六. Python函数进阶
1. 函数的多返回值
# 演示使用多个变量,接收多个返回值
def test_return():
return 1, "hello", True
x, y, z = test_return()
print(x)
print(y)
print(z)
2. 函数的多种参数使用形式
-
函数参数种类
使用方式的不同,常见4中参数的使用方式:
位置参数、关键字参数、缺省参数、不定长参数
-
位置参数:调用函数时,根据函数定义的参数位置来传递函数【注意:传递的参数和定义的参数的顺序及个数必须一致】
-
关键字参数:函数调用时通过”键 = 值“形式传递参数
作用:可以让函数更加清晰,容易使用,同时也消除了参数的顺序要求【注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序】
-
缺省参数:也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值【注意:所有位置参数必须出现在默认参数前,包括函数定义和调用】
作用:当调用函数时没有传递参数,就会使用默认缺省参数对应的值
-
不定长参数:也叫可变参数,用于不确定调用时会传递多少个参数的场景
作用:当调用函数时不确定参数个数时,可以使用不定长参数
- 位置传递的不定长【注意:传进的所有参数都会被不定长参数收集,它会根据传进参数的位置合并为一个元组】
- 关键字传递的不定长【注意:参数是键 - 值形式下,所有的键值对会被接收,然后组成dict】
def user_info(name, age, gender):
print(f"姓名是:{name},年龄是:{age},性别是:{gender}")
# 位置参数(默认使用形式)
user_info("胡图图", 20, "男")
# 关键字参数
user_info(name="胡英俊", gender='男', age=40)
# 缺省参数
def user_info2(name, age, gender='男'):
print(f"姓名是:{name},年龄是:{age},性别是:{gender}")
user_info2('牛爷爷', 70)
# 不定长 - 位置不定长,*号
# 不定长定义的形参会作为元组存在,接收不定长数量的参数传入
def user_info3(*args):
print(f"args参数的类型是:{type(args)},内容是:{args}")
user_info3(1, 2, 3, 4, '小美')
# 不定长 - 关键字不定长,**号
def user_info4(**kwargs):
print(f"kwargs参数的类型是:{type(kwargs)},内容是:{kwargs}")
user_info4(name="胡图图", age=10)
3. 函数作为参数传递
- 是计算逻辑的传递,不是数据的传递
- 函数本身可以作为参数,传入另一个函数中进行使用
- 将函数传入的作用在于:传入计算逻辑而非传入数据
七. Python文件操作
1. 文件的编码
-
编码技术:即翻译的规则,记录了如何将内容翻译成二进制,以及如何将二进制翻译回可识别内容
-
常用编码:UTF-8, GBK,Big5
不同编码翻译内容不一样
2. 文件的读取
- OS以文件为单位管理磁盘中的数据,一般来说,文件可以分为文本文件、视频文件、音频文件、图像文件、可执行文件等
- 主要操作:打开、关闭、读、写
- 通常可分为三步:打开文件、读写文件、关闭文件
- 常用方法:
方法 | 解释 |
---|---|
open() | 可以打开或者创建一个新文件 |
文件对象.read(num) | 表示从文件中读取的数据的长度(单位是字节),如果没有传入num,则读全部 |
文件对象.readlines() | 按照行的形式八整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素 |
文件对象.readline() | 一次读取一行内容 |
文件对象.close() | 关闭文件对象,也就是关闭对文件的使用 |
with open 语法 | 可以在操作完成后自动关闭文件,避免遗忘close方法 |
"""
name:要打开的目标文件名的字符串(可以包含文件所在的具体路径)
mode:设置打开文件的模式(访问模式):只读、写入、追加等
encoding:编码格式(一般使用UTF-8)
"""
open(name,mode,encoding)
"""
mode =
r:以只读方式打开文件,文件的指针将会放在文件的开头,这是默认方式
w:打开一个文件只用于写入,如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除,如果文件不存在,则创建新文件
a:打开一个文件用于追加,如果该文件已经存在,新内容会被写入已有内容之后,如果文件不存在,创建新文件并写入
"""
# 打开文件
f = open("D:/桌面/python/test.txt", "r", encoding="UTF-8")
print(type(f))
# 读取文件 read()
print(f"读取10个字节的结果:{f.read(10)}")
print(f"读取全部内容的结果:{f.read()}") # 多次调用read会在上一次调用基础上调用
# 读取文件 readLines() 读取文件的全部行,封装到列表中
lines = f.readlines()
print(f"lines对象的类型:{type(lines)}")
print(f"lines对象的内容是:{lines}")
# 读取文件 readLine()
line1 = f.readline()
line2 = f.readline()
line3 = f.readline()
print(f"第一行数据是{line1}")
print(f"第二行数据是{line2}")
print(f"第三行数据是{line3}")
# for循环读取文件行
for line in f:
print(f"每一行数据:{line}")
# 文件的关闭
f.close()
# with open 语法操作文件
with open("D:/桌面/python/test.txt", "r", encoding="UTF-8") as f:
for line in f:
print(f"每一行的数据{line}")
3. 文件的写入
f.open("文件路径", "w")
f.write()
# 内容刷新
f.flush()
- 直接调用write,内容并未真正写入文件,但是会积攒在程序的内存中,也就是缓冲区
- 当调用flush时候,内容才会被真正写入文件
- 避免频繁操作硬盘
4. 文件的追加
f.open("文件路径", "a")
f.write()
# 内容刷新
f.flush()
- a模式,文件不存在会创建文件
- a模式,文件存在则会在最后追加文件
八. 异常
1. 了解异常
所谓异常就是BUG
2. 异常的捕获方法
捕获异常的作用:提前假设某处出现异常,做好提前准备,当真的出现异常的时候,可以有后续手段
捕获常规异常:
try:
可能发生错误的代码
except:
如果出现异常执行的代码
捕获指定的异常:
try:
print(name)
except NameError as e:
print('name变量名称未定义错误')
捕获多个异常:
try:
print(1/0)
except (NameError,AeroDivisionError):
print("")
异常else:
try:
print(1)
except Exception as e:
print(e)
else
print("我是else,是没有出现异常时执行的代码")
异常的finally:
try:
...
except Exception as e:
....
else:
...
finally:
....
3. 异常的传递
异常具有传递性
# 定义一个出现异常的方法
def func1():
print("func1 开始执行")
num = 1 / 0 # 除0 肯定有异常
print("func1 结束执行")
# 定义一个无异常的方法,调用上面的方法
def func2():
print("func2 开始执行")
func1()
print("func2 结束执行")
# 定义一个方法,调用前面的方法
def main():
try:
func2()
except Exception as e:
print(f"出现异常,异常信息是:{e}")
main()
4. Python模块
-
Python模块,是一个python文件,以.py结尾,模块能定义函数,类和变量,模块里也能包含可执行的代码
-
模块的作用:
- python中有很多各种不同的模块,每一个模块都能帮助我们实现一些功能,比如实现和时间相关的可以使用time模块。可以将模块看成一个工具包,每一个工具包都有各种不同的工具供我们使用而实现不同的功能
-
模块的导入方式:
[from 模块名] import [模块|类 | 变量 | 函数 | *][as 别名]
- import 模块名
- from 模块名 import 类、变量、方法等
- from 模块名 import *
- import 模块名 as 别名
- from 模块名 import 功能名 as 别名
-
自定义模块
5. Python包
-
从物理上来看,包就是一个包含了一个init.py 文件的文件夹,该文件夹可以用于包含多个模块文件,从逻辑上来看,包的本质依旧是模块
-
导入包
import 包名.模块名 包名.模块名.目标
6. 安装第三方包
pip install 包
pip install -i 镜像网站 包
九. 可视化综合案例(折线图)
10.1 json数据格式
JSON是一种轻量级的数据交互格式,可以按照JSON指定的格式去组织和封装数据
-
JSON本质上是一个带有特定格式的字符串
-
在Python JSON要么是一个单独的字典或者内部元素都是字典的列表
-
主要功能
- 是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互
-
各个编程语言存储数据的容器不尽相同,例如:在Python中有字典dict这样的数据类型而在其他语言中可能没有对应的字典。
可以使用JSON数据格式作为数据中转站
-
json格式的数据要求很严格(字典)
# 实例 {"name":"admin", "age":18}
-
python数据和json数据的互相转换
# 导入json模块 import json # 准备符合格式json要求的python数据 data = [{"name": "wang", "age":19},{"name": "li", "age":79}] # 通过json.dumps(data)方法把python数据转化为了json数据 data = json.dumps(data) # 通过json.loads(data)方法把json数据转化为了python数据 data = json.loads(data)
10.2 pyecharts模块的入门使用
导入
# 显示虚拟环境
conda env list
# 进入虚拟环境
conda activate 环境名
# 安装
pip install pyecharts
-
pyecharts入门:基础折线图
# 导包,导入line功能构建折线图兑现 from pyecharts.charts import Line # 得到折线图对象 line = Line() # 添加x轴数据 line.add_xaxis(["中国", "美国", "日本"]) # 添加y轴数据 line.add_yaxis("GDP",[30, 20 ,10]) # 生成图表 line.render()
-
pyecharts模块中有很对的配置选项,常用到2个类别的选项
-
全局配置选项
全局配置通过set_global_opts方法来进行配置,相应的选项
TitleOpts 设置标题 LegendOpts 图例配置项 ToolboxOpts 工具箱配置项 VisualMapOpts 视觉映射配置项 TooltipOpts 提示框配置项 DataZoomOpts 区域缩放配置项 -
系列配置选项
-
10.3 数据处理
网站:ab173.com 查看json数据
10.4 折线图
- 导入json
import json
- 处理数据以美国为例
f_us = open("D:/桌面/折线图数据/美国.txt", "r", encoding="UTF-8")
us_data = f_us.read() # 美国的全部内容
- 规范化数据
# 去掉不和JSON规范的开头
us_data = us_data.replace("jsonp_1629344292311_69436(", "")
# 去掉和JSON规范的结尾
us_data = us_data[:-2] # 使用切片去除最后一个不和规范的数据
- JSON转python字典
us_dict = json.loads(us_data)
# 获取trend key
us_trend_data = us_dict['data'][0]['trend']
- 获取x,y轴数据
# 获取日期数据,用于x轴,取2020年(到314结束)
us_x_data = us_trend_data['updateDate'][:314]
# 获取确认数据,用于y轴,取2020年(到314结束)
us_y_data = us_trend_data['list'][0]['data'][:314]
- 生成图表
line = Line() # 获取折线图对象
- 添加x,y轴数据
line.add_xaxis(us_x_data) # x轴是公用的,所以使用一个国家的数据即可
# label_opts=LabelOpts(is_show=False) 局部设置,数据不显示
line.add_yaxis("美国确诊人数", us_y_data, label_opts=LabelOpts(is_show=False))
- 生成图表
# 调用render方法
line.render()
# 关闭文件对象
f_us.close()
f_jp.close()
f_in.close()
- 全局设置
line.set_global_opts(
# 标题设置
title_opts=TitleOpts(title="2020年美日印三国确证人数对比折线图", pos_left="center", pos_bottom="1%"),
legend_opts=LegendOpts(is_show=True),
toolbox_opts=ToolboxOpts(is_show=True),
visualmap_opts=VisualMapOpts(is_show=True)
)
- 完整示例
import json
from pyecharts.charts import Line
from pyecharts.options import TitleOpts, LabelOpts, LegendOpts, ToolboxOpts, VisualMapOpts
# 处理数据
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)
# print(type(us_dict))
# print(us_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']
# print(type(trend_data))
# print(trend_data)
# 获取日期数据,用于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]
# print(x_data)
# 获取确认数据,用于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轴数据
# label_opts=LabelOpts(is_show=False) 局部设置,数据不显示
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%"),
legend_opts=LegendOpts(is_show=True),
toolbox_opts=ToolboxOpts(is_show=True),
visualmap_opts=VisualMapOpts(is_show=True)
)
# 调用render方法生成图表
line.render()
# 关闭文件对象
f_us.close()
f_jp.close()
f_in.close()
十. 地图
1. 基础地图使用
2. 疫情地图-国内疫情地图
3. 疫情地图-省级疫情地图
十一. 动态柱状图
1. 基础柱状图
通过Bar构建基础柱状图
2. 基础时间线柱状图
-
Timeline() 时间线
柱状图描述的是分类数据,回答的是每一个分类中有多少这个问题,这是柱状图的主要特点,同时柱状图很难动态的描述一个趋势性的数据,pyecharts提供了一种解决方案- 时间线
-
如果说Bar,Line对象是一张图标,时间线就是创建一个一维的x轴,轴上的每个点就是一个图表对象
# 导包
from pyecharts.charts import Timeline
timeline = TimeLine()
- 自动播放
# 自动播放设置
timeline.add_schema(
play_interval=1000, # 自动播放的时间间隔,单位是毫秒
is_timeline_show=True, # 是否自动播放的时候显示时间线
is_auto_play=True, # 是否自动播放
is_loop_play=True # 是否循环自动播放
)
- 设置主题
timeline = Timeline({"theme": ThemeType.ROMANTIC})
3. gdp动态柱状图绘制
-
列表的sort方法
列表.sort(key = 选择排序依据的函数, reverse = True|False)
- 参数key:要求传入一个函数,表示将列表的每一个元素都传入函数中,返回排序的结果
- 参数reverse,是否反转排序结果,True表示降序,False表示升序
from pyecharts.charts import Bar, Timeline
from pyecharts.options import *
from pyecharts.globals import ThemeType
# 读取数据
f = open("D:/桌面/python/资料/可视化案例数据/动态柱状图数据/1960-2019全球GDP数据.csv", "r", encoding="GB2312")
# .readlines() 打开是一个列表
data_lines = f.readlines()
# 关闭文件
f.close()
# 删除第一条数据
data_lines.pop(0)
# 将数据转化为字典存储
# 定义一个字典对象
# 格式为:{1960: [[美国, 123], [中国, 321]....], 1961:[[美国, 123], [中国, 321]....]......}
data_dict = {}
for line in data_lines:
year = int(line.split(",")[0]) # 年份
country = line.split(",")[1] # 国家
gdp = float(line.split(",")[2]) # gdp数据
# 数据格式化
try:
data_dict[year].append([country, gdp])
# 如果没有key, 就捕获异常,新建一个列表
except KeyError:
data_dict[year] = []
data_dict[year].append([country, gdp])
# print(data_dict)
# 创建时间线对象
# 设置颜色格式
timeline = Timeline({"theme": ThemeType.LIGHT})
# 排序年份
sorted_year_list = sorted(data_dict.keys())
for year in sorted_year_list:
# 通过gdp进行排序
data_dict[year].sort(key=lambda element: element[1], reverse=True)
# 取出本年份前8名的国家
year_data = data_dict[year][0:8]
x_data = []
y_data = []
# for循环每一年的数据,基于每一年的数据,创建每一年的bar对象
for country_gdp in year_data:
x_data.append(country_gdp[0]) # x轴添加国家
y_data.append(country_gdp[1] / 100000000) # y轴添加gdp
# 构建柱状图
bar = Bar()
# 调转x和y轴数据完成从大到小
x_data.reverse()
y_data.reverse()
bar.add_xaxis(x_data)
# 设置数值标签在右侧 label_opts=LabelOpts(position="right")
bar.add_yaxis("GDP(亿)", y_data, label_opts=LabelOpts(position="right"))
# 反转x,y轴
bar.reversal_axis()
# 设置每一年的图表的标题
bar.set_global_opts(
title_opts=TitleOpts(title=f"{year}年全球前八GDP数据")
)
# 在for中,将每一年的bar对象添加到时间线中
timeline.add(bar, str(year))
# 设置时间线自动播放
timeline.add_schema(
play_interval=1000,
is_timeline_show=True,
is_auto_play=True,
is_loop_play=False
)
# 绘图
timeline.render("1960-2019全球GDP前八国家.html")
十二、面向对象
1. 初识对象
使用对象组织数据
在程序中是可以做到和生活中那样,设计表格、生产表格、填写表格的组织形式的
-
在程序中设计表格,称之为:设计类(class)
class Sudent: name = None # 记录学生姓名
-
在程序中打印生产表格,称之为:创建对象
stu_1 = Student() # 基于类创建对象
-
在程序中填写表格,称之为:对象属性赋值
stu_1.name = "胡图图" # 为学生1对象赋予名称属性值
2. 成员方法
类的定义和使用语法
class 类名称:
类的属性
类的行为
- class是关键字,表示要定义类了
- 类的属性,即定义在类中的变量(成员变量)数据
- 类的行为,即定义在类中的函数(成员方法)函数
创建类对象的语法
对象 = 类名称()
成员方法
在类中定义成员方法和定义函数基本一致
def 方法名(self, 形参1, ....形参n):
方法体
self关键字是成员方法定义的时候,必须填写的
- 它用来表示类对象自身的意思
- 当我们使用类对象调用方法的时候,self会被python自动传入,在传参的时候可以忽略
- 在方法内部,想要访问类的成员变量,必须使用self
# 定义一个带有成员方法的类
class Student:
name = None # 学生姓名
def say_hi(self):
print(f"大家好啊,我是{self.name},初次见面,请多关照")
def say_hi2(self, msg):
print(f"大家好,我是{self.name},{msg}") # 想要访问成员属性,必须使用self关键字,外部传入参数则不需要
stu_1 = Student()
stu_1.name = "胡图图"
stu_1.say_hi()
stu_1.say_hi2("我的耳朵很大")
stu_2 = Student()
stu_2.name = "小美"
stu_2.say_hi()
stu_2.say_hi2("我最爱漂亮")
3. 类和对象
- 类包含属性和行为,所以使用类描述现实世界事物是很合适的
- 类相当于图纸,对象是基于图纸生产的具体实体
- 面向对象编程就是,使用对象进行编程
# 设计一个闹钟类
class Clock:
id = None
price = None
def ring(self):
import winsound
winsound.Beep(2000, 3000)
# 构建两个闹钟对象并使其工作
clock1 = Clock()
clock1.id = "2023"
clock1.price = 888
print(f"闹钟ID:{clock1.id}, 价格是:{clock1.price}")
clock1.ring()
clock2 = Clock()
clock2.id = "2024"
clock2.price = 888
print(f"闹钟ID:{clock2.id}, 价格是:{clock2.price}")
clock2.ring()
4. 构造方法
Python类可是使用
__init__(self,...) # 构造方法
可以实现
- 在创建类对象(构造类)的时候,会自动执行
- 在创建类对象(构造类)的时候,将传入参数自动传递给init方法使用
class Student:
# # 可以省略
# name = None
# age = None
# tel = None
def __init__(self, name, age, tel):
self.name = name
self.age = age
self.tel = tel
print("Student类创建了一个类对象")
stu = Student("胡图图", 6, "1111111111")
print(stu.name)
print(stu.age)
print(stu.tel)
5. 其他内置方法
内置的类方法,各自有其特殊的功能,称之为魔术方法
方法 | 作用 |
---|---|
init | 构造方法,可用于构建类对象的时候设置初始化行为 |
str | 字符串方法,用于实现类对象转化字符串的行为 |
lt | 用于两个类对象小于,大于符号比较 |
le | 用于两个类对象小于等于,大于等于符号比较 |
eq | 用于两个类对象== 符号比较 |
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
# __str__魔术方法
def __str__(self):
return f"Student类对象, name{self.name}, age: {self.age}"
# __lt__魔术方法
def __lt__(self, other):
return self.age < other.age
# __le__魔术方法
def __le__(self, other):
return self.age <= other.age
# __eq__魔术方法
def __eq__(self, other):
return self.age == other.age
stu1 = Student("胡图图", 6)
stu2 = Student("壮壮", 8)
stu3 = Student("小美", 6)
# __str__, 如果没有该方法,则输出内存地址
print(stu1)
print(str(stu1))
# __lt__,直接对两个对象进行比较是不可以的,但是在类中实现__lt__方法
# 即可同时完成:小于符号和大于符号两种比较
print(stu1 < stu2)
print(stu1 > stu2)
# __le__
print(stu1 <= stu3)
# __eq__
print(stu1 == stu3)
6. 封装
封装:将现实世界事物在类中描述为属性和方法,即为封装
面向对象包含三大特性:
- 封装
- 继承
- 多态
私有成员:现实世界有部分属性和行为不公开对使用者开放,同样在类中描述属性和方法的时候也需要达到这个要求,就需要定义私有成员了
类中提供了私有成员的形式来支持
- 私有成员变量
- 私有成员方法
定义私有成员的方式:
# 私有成员变量
__变量名
# 私有成员方法
def __方法名:
- 私有方法无法直接被类对象使用
- 私有变量无法赋值,也无法获取值
私有成员的访问权限
- 类对象无法访问私有成员
- 类中的其他成员可以访问私有成员
# 设计一个类,用来描述手机
class Phone:
# 提供私有成员变量:__is_5g_enable
__is_5g_enable = True # 5g状态
# 提供私有成员方法:__check_5g()
def __check_5g(self):
if self.__is_5g_enable:
print("5g开启")
else:
print("5g关闭,使用4g网络")
# 提供公开成员方法:call_by_5g()
def call_by_5g(self):
self.__check_5g()
print("正在通话中")
phone = Phone()
phone.call_by_5g()
7. 继承
class 类名(父类名):
类内容体
继承可以分为单继承和多继承
多继承:
Python的类之间也支持多继承,即一个类,可以继承多个父类
class 类名(父类1,父类2....父类N):
类内容体
多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级
即:先继承的保留,后继承的被覆盖
pass关键字:占位语句,补全代码,无实义
8. 复写父类成员方法和调用父类成员
-
复写:子类继承父类的成员方法后,如果对其不满意,可以进行复写
即:在子类中重新定义同名的属性或方法即可
class Phone:
IMEI = None
producer = "hututu"
def call_by_5g(self):
print("使用5g通话")
# 定义子类,复写父类成员
class MyPhone(Phone):
producer = "xiaomei" # 复写父类的成员属性
def call_by_5g(self):
print("开启CPU单核模式,确保通话的时候省电")
print("使用5g网络进行通话")
print("关闭CPU单核模式,确保性能畅通")
phone = MyPhone()
phone.call_by_5g()
print(phone.producer)
调用父类同名成员
一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员,如果需要使用被复写的父类的成员,需要特殊的调用方法:
# 调用父类成员
父类名.成员变量
父类名.成员方法(self)
# 使用super()调用父类成员
super().成员变量
super().成员方法()
- 注意:只可以在子类内部调用父类的同名成员,子类的实体类对象调用默认是调用子类复写的
9. 类型注解
9.1 变量的类型注解
Python在3.5版本的时候就引入了类型注解,以方便静态类型检查工具,IDE等第三方工具
**类型注解:**在代码中设计数据交互的地方,提供数据类型的注解
主要功能:
- 帮助第三方IDE工具(PCharm)对代码进行类型推断,协助做代码提示
- 帮助开发者自身对变量进行类型注释
支持:
- 变量的类型注解
- 函数(方法)形参列表和返回值的类型注解
变量注解的语法:
变量:类型
#type:类型
- 元组类型设置类型详细注解,需要将每一个元素都标记出来
- 字典类型设置类型详细注解,需要2个类型,第一个key,第二个value
# 基本数据类型注解
import json
import random
from typing import List, Tuple, Dict
var_1: int = 10
var_2: str = "hututu"
var_3: bool = True
# 类对象类型注解
class Student:
pass
stu: Student = Student()
# 基本容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_dict: dict = {"胡图图": 99}
# 容器类型详细注解
my_list1: List[int] = [1, 2, 3]
my_tuple1: Tuple[int, str, bool] = (1, "hututu", True)
my_dict1: Dict[str, int] = {"胡图图": 99}
# 在注释中进行类型注解
# alt+enter 自动导包
var_11 = random.randint(1, 10) # type: int
var_12 = json.loads('{"name": "胡图图"}') # type: dict[str, str]
def fun():
return 10
var_13 = fun() # type: int
- 类型注解只是提示性的,并非决定性,数据类型和注解类型无法对应也不会导致错误
9.2 函数和方法的类型注解
函数(方法)的类型注解-形参注解语法:
def 函数方法名(形参名:类型,形参名:类型....):
pass
函数方法的类型注解-返回值注解语法:
def 函数方法名(形参名:类型,形参名:类型....) ->返回值类型:
pass
# 对形参进行类型注解
def add(x: int, y: int):
return x + y
add(1, 2)
# 对返回值进行类型注解
def fun(data: list) -> list:
return data
fun([1, 2, 3])
9.3 Union类型注解
可以定义联合类型注解
Union[类型,....,类型]
# 使用Union必须先导包
from typing import Union, List
my_list: List[Union[int, str]] = [1, 2, "hututu", "xiaomei"]
def func(data: Union[int, str]) -> Union[int, str]:
pass
10. 多态
-
多态:多种状态,即完成某个行为时,使用不同的对象会得到不同的状态
即:同样的行为(函数),传入不同的对象,得到不同的状态
-
多态常用于继承关系上
-
抽象类(接口):含有抽象方法(方法体是空实现的[pass])的类
抽象类相当于定义一个标准,包含了一些抽象的方法,要求子类必须实现
抽象类的作用:做顶层实际标准,以便子类做具体实现,也是对子类的一种软性约束,要求子类必须复写父类的一些方法,并配合多态使用,获得不同的工作状态。
# 演示抽象类
class AC:
def cool_wind(self):
"""制冷"""
pass
def hot_wind(self):
"""制热"""
pass
def swing_l_r(self):
"""左右摆风"""
pass
# 子类
class Midea_AC(AC):
def cool_wind(self):
print("美的空调制冷的具体实现")
def hot_wind(self):
print("美的空调制热的具体实现")
def swing_l_r(self):
print("美的空调左右摆风的具体实现")
# 具体类的实现
class GREE_AC(AC):
def cool_wind(self):
print("格力空调制冷的具体实现")
def hot_wind(self):
print("格力空调制热的具体实现")
def swing_l_r(self):
print("格力空调左右摆风的具体实现")
def make_cool(ac: AC):
ac.cool_wind()
midea_ac = Midea_AC()
gree_ac = GREE_AC()
make_cool(midea_ac)
make_cool(gree_ac)
11. 综合案例
data_define.py
"""
数据定义的类
"""
class Record:
def __init__(self, data, order_id, money, province):
self.data = data # 订单日期
self.order_id = order_id # 订单ID
self.money = money # 订单金额
self.province = province # 销售省份
# 控制输出为字符串而不是内存地址
def __str__(self):
return f"{self.data}, {self.order_id}, {self.money}, {self.province}"
file_define.py
"""
和文件相关的类定义
"""
import json
from typing import List
from data_define import Record
# 先定义一个抽象类用来做顶层设计,确定有哪些功能需要实现
class FileReader:
def read_data(self) -> List[Record]:
"""读取文件的数据,将读取的每一条数据都转化为Record对象,将他们都封装到list内返回即可"""
pass
class TextFileReader(FileReader):
def __init__(self, path):
self.path = path # 定义成员变量记录文件的路径
# 复写(实现抽象方法)父类的方法
def read_data(self) -> List[Record]:
f = open(self.path, "r", encoding="UTF-8")
record_list: List[Record] = []
for line in f.readlines():
line = line.strip() # 消除读取到的每一行数据中的\n
# print(line)
data_list = line.split(",")
record = Record(data_list[0], data_list[1], int(data_list[2]), data_list[3])
record_list.append(record)
f.close()
return record_list
class JsonFileReader(FileReader):
def __init__(self, path):
self.path = path # 定义成员变量记录文件的路径
def read_data(self) -> List[Record]:
f = open(self.path, "r", encoding="UTF-8")
record_list: List[Record] = []
for line in f.readlines():
# 将json数据类型转化为字典数据类型
data_dict = json.loads(line)
record = Record(data_dict["date"], data_dict["order_id"], int(data_dict["money"]), data_dict["province"])
record_list.append(record)
f.close()
return record_list
# 测试
if __name__ == '__main__':
# text_file_reader = TextFileReader("D:/桌面/python/资料/2011年1月销售数据.txt")
json_file_reader = JsonFileReader("D:/桌面/2011年2月销售数据JSON.txt")
# text_file_reader.read_data()
list2 = json_file_reader.read_data()
for l in list2:
print(l)
main.py
"""实现步骤:
1. 设计一个类,可以完成数据的封装
2. 设计一个抽象类,定义文件读取的相关功能,并使用子类实现具体功能
3. 读取文件,生产数据对象
4. 进行数据需求的逻辑计算(计算每一天的销售额)
5. 通过PyEcharts进行图形绘制
"""
from typing import List
from file_define import FileReader, TextFileReader, JsonFileReader
from data_define import Record
from pyecharts.charts import Bar
from pyecharts.options import *
from pyecharts.globals import ThemeType
text_file_reader = TextFileReader("D:/桌面/python/资料/2011年1月销售数据.txt")
json_file_reader = JsonFileReader("D:/桌面/2011年2月销售数据JSON.txt")
jan_data: List[Record] = text_file_reader.read_data()
feb_data: List[Record] = json_file_reader.read_data()
# 将2个月份的数据合并为1个list来存储
all_data: List[Record] = jan_data + feb_data
# 开始进行数据计算
# key:日期, value:当天营业额
data_dict = {}
for record in all_data:
if record.data in data_dict.keys():
# 当前日期已经有记录了,所以和老记录累加即可
data_dict[record.data] += record.money
else:
data_dict[record.data] = record.money
# print(data_dict)
# 可视化图表开发
bar = Bar(init_opts=InitOpts(theme=ThemeType.LIGHT))
bar.add_xaxis(list(data_dict.keys())) # 添加x轴数据
# label_opts=LabelOpts(is_show=False) 不显示数据
bar.add_yaxis("销售额", list(data_dict.values()), label_opts=LabelOpts(is_show=False)) # 添加y轴数据
bar.set_global_opts(
title_opts=TitleOpts(title="每日销售额")
)
bar.render("每日销售额柱状图.html")
十三、SQL语言
1. SQL基础和DDL
-
SQL:结构化查询语言,用于访问和处理数据库的标准计算机语言
-
由于数据库管理系统的功能非常多,不仅仅是存储数据,还要包含:数据的管理、表的管理、库的管理、账户管理、权限管理
SQL分为以下几类
名称 作用 DDL(数据定义语言) 库的创建删除、表的创建删除 DML(数据操纵语言) 新增数据、删除数据、修改数据 DCL(数据控制语言) 新增用户、删除用户、密码修改、权限管理 DQL(数据查询语言) 基于需求查询和计算数据 -
SQL特点
-
大小写不敏感
-
以; 作为结束
-
支持注释
--单行注释 # 单行注释 /*多行 注释*/
-
-
DDL-库管理
要求 语句 查看数据库 show databases; 使用数据库 use 数据库名称; 创建数据库 create database 数据库名称 [charset UTF-8]; 删除数据库 drop database 数据库名称; 查看当前使用的数据库 select database(); DDL-表管理
要求 语句 查看哪些表 show tables; 删除表 drop table if exists 表名称; 创建表 create table 表名称( 列名称 列类型;…);
-- 列类型有
int
float
varchar
date
timestamp
2. DML
关键字 | 作用 |
---|---|
insert | 插入 |
delete | 删除 |
update | 更新 |
数据插入insert
insert into 表[(列1, 列2.....,列N)]
values[(值1,.....值N),
(值1,.....值N),
......]
数据删除delete
delete from 表名称
where 条件判断
数据更行update
update 表名
set 值 = 列
where 判断语句
3. DQL
3.1 基础查询
在SQL中,通过select关键字开头的SQL语句,进行数据的查询
select 字段列表
from 表
3.2 group by 进行分组聚合查询
select 字段|聚合函数
from 表
where 判断条件
group by 列
- 聚合函数
函数名 | 作用 |
---|---|
sum(列) | 求和 |
avg(列) | 求平均值 |
min(列) | 求最小值 |
max(列) | 求最大值 |
count(列|*) | 求数量 |
3.3 排序分页
结果排序
select 列|聚合函数|*
from 表
where 判断语句
group by
order by [ASC,DESC]
结果分页限制:使用limit关键字,对查询结果进行数量限制或者分页显示
select 列|聚合函数|*
from 表
where 判断语句
group by
order by [ASC,DESC]
limit n[,m]
4. python操作mysql基础使用
安装第三方库
pip install pymysql
- 创建MySql的数据库链接
from pymysql import Connection
# 创建到mysql数据库的链接
conn = Connection(
host="localhost", # 主机名(IP)
port=3306, # 端口
user="root", # 账户
password="******" # 密码
)
# 关闭链接
conn.close()
- 执行非查询性质的sql语句
# 执行非查询性质SQL
cursor = conn.cursor() # 获取到游标对象
# 选择数据库
conn.select_db("test")
# 执行sql
cursor.execute("create table test_pymysql(id int);")
- 执行查询性质的sql语句
# 执行查询性质SQL
cursor = conn.cursor() # 获取到游标对象
# 选择数据库
conn.select_db("world")
# 执行sql
cursor.execute("select * from student")
results = cursor.fetchall() # 返回一个大元组
for r in results:
print(r)
5. Python操作MySql数据插入
- pymysql库在执行对数据库有修改操作的行为时,是需要通过链接对象的commit或者成员方法来进行确认的
手动commit
from pymysql import Connection
# 构建到Mysql数据库的链接
conn = Connection(
host="localhost",
port=3306,
user="root",
password="******"
)
# 执行非查询性质的SQL
# 获取到游标对象
cursor = conn.cursor()
# 选择数据库
conn.select_db("world")
# 执行sql语句
cursor.execute("insert into student values(7,'牛爷爷',79)")
# 通过commit确认
conn.commit()
# 关闭链接
conn.close()
自动commit
# 构建到Mysql数据库的链接
conn = Connection(
host="localhost",
port=3306,
user="root",
password="******",
autocommit=True
)
6. 综合案例
-
DDL定义
-
本次需要新建一个数据库来使用,数据库名称:py_sql
create database py_sql charset utf8;
-
基于数据结构,得到建表语句
create table orders( order_date date, order_id Varchar(255), money int, province varchar(10) );
-
-
实现
# 构建MySQL链接对象 conn = Connection( host="localhost", port=3306, user="root", password="******", autocommit=True ) # 获得游标对象 cursor = conn.cursor() # 选择数据库 conn.select_db("py_sql") # 组织SQL语句 for record in all_data: sql = f"insert into orders(order_date,order_id,money,province) " \ f"values('{record.data}', '{record.order_id}', {record.money},'{record.province}')" # print(sql) # 执行sql语句 cursor.execute(sql) # 关闭链接对象 conn.close()