文章目录
- Python学习笔记
- python 基础语法
Python学习笔记
python 基础语法
一、字面量
在 python 中,有 6 种常见的数据类型:
类型 | 描述 | 说明 |
---|---|---|
数字(Number) | 整数(int)、浮点数(float)、复数(complex)、布尔(bool) | 复数(complex):如4+3j,以j结尾表示复数 |
字符串(String) | - | - |
列表(List) | 有序的可变序列 | Py 中使用最频繁的数据类型,可有序记录一堆数据 |
元组(Tuple) | 有序的不可变序列 | 可有序记录一堆不可变的 py 数据集合 |
集合(Set) | 无序不重复集合 | 可无序记录一堆不可变的 py 数据集合 |
字典(Dictionary) | 无序 key-value 集合 | 可无序记录一堆 key- value 型的 py 数据集合 |
二、转换函数
- int(x):将 x 转换为一个整数
- float(x):将 x 转换为一个浮点数
- str(x):将对象 x 转换为字符串
三、python 命令规则
在 python 的命名规则中,大小写敏感,标识符命名中,只允许出现:
- 英文
- 中文(不推荐使用)
- 数字(不可用作开头)
- 下划线(_)
除了这四类元素,其他任何内容都不被允许。关键字也不被允许使用,关键字如下:
四、python 运算规则
除了常见的 +,-,*,/;还有
- //: 取整数(10 // 3 = 3)
- %:取余(10 % 3 = 1)
- **:指数(2 ** 3 = 8)
五、字符串格式化
- %s:其中 % 表示我要占位,s 表示将变量变成字符串放入占位的地方。
举例:name = "abc" message = "cde%s" % name print(message) # cdeabc
class_num = 50 # 班级人数 avg_score = 80 print("该班级总共有:%s人,平均分数为:%s" % (class_num, avg_score)) # 该班级总共有:50人,平均分数为:80
在 python 中,最常用的是如下三类占位符:
- %s:将内容转换成字符串,放入占位位置。
- %d:将内容转换成整数,放入占位位置。
- %f:将内容转换成浮点数,放入占位位置。
六、数据输入 input
name = input()
print("我知道了,你是:%s" % name)
七、py 中 if 的使用
age = 88
if age >= 18:
print("我已经成年了")
print("时间过的真快呀")
age = 8
if age >= 18:
print("我已经成年了")
else:
print("你还未成年")
age = 8
if age >= 18:
print("我已经成年了")
elif height > 180:
print("你只是长的像大人")
else:
print("你还未成年")
八、随机函数
import random
num = random.randint(1, 10)
guess_num = int(input("输入你要猜测的数字:"))
if guess_num == num:
print("恭喜,第一次就猜中了")
else:
if guess_num > num:
print("你猜测的数字大了")
else:
print("你猜测的数字小了")
九、while 循环的基础应用
i = 0
while i < 10:
print("循环了")
i += 1
十、while 循环九九乘法表
i = 1
while i <= 9:
j = 1
while j <= i:
print(f"{j} * {i} = {j * i}\t", end="")
j += 1
i += 1
print()
十一、for 循环
- range 语法1 range(num)
- range 语法2 range(num1, num2)
- range 语法3 range(num1, num2, step):step 为步长
for x in range(5, 10):
print(x)
十二、嵌套 for 循环
for i in range(1, 101):
print(f"今天是第{i}天")
for j in range(1, 11):
print(f"今天的第{j}次循环")
十三、嵌套 for 循环打印九九乘法表
for i in range (1,10):
for j in range (1,10):
print(i,"X",j,"=",i*j,"\t",end="")#end=""表示不换行
if i == j:
print("")
break
十四、自定义函数
-
无返回值:
def fun(str): count = 0 for i in str: count += 1 print(f"字符串{str}的长度为:", count)
-
有返回值:
def sum(number1, number2): return number1 + number2 print(sum(2, 5))
-
函数返回值之 None 类型:
思考:如果函数没有使用 return 语句返回数据,那么函数有返回值吗?答案是有的。
py 中有一个特殊的字面量:None,其类型是:<class ‘NoneType’> 无返回值的函数,实际上就是返回了:None 这个字面量。def say_hi(): print("你好呀") result = say_hi() # 你好呀 print(f"无返回值函数,返回的内容是:{result}") # 无返回值函数,返回的内容是:None print(f"无返回值函数,返回的内容类型是:{type(result)}") # 无返回值函数,返回的内容类型是:<class 'NoneType'>
十五、global 关键字
定义在函数外的为全局变量,定义在函数内的为局部变量。如果在函数内直接修改全局变量,不能成功,但是使用 global 关键字,可以使函数内部声明的变量为全局变量,这样才能修改成功。
- 不使用 global 关键字:
x = 10 def fun(): x = 20 fun() print(x) # 10
- 使用 global 关键字:
x = 10 def fun(): global x x = 20 fun() print(x) # 20
十六、python 数据容器
数据容器有如下特点:
- 是否支持重复元素
- 是否可以修改
- 是否有序,等
数据容器分为 5 类:列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)。
1、列表(list)
基本语法:
# 字面量
[元素1、元素2、元素3、元素4,...]
# 定义变量
变量名称 = [元素1、元素2、元素3、元素4,...]
# 定义空列表
变量名称 = []
定义变量 = list()
案例:
student_list = ["张三", "李四", "王五", "赵六"] # 该list不同于java,不受泛型限制
for i in range(0, len(student_list)):
print(student_list[i]) # 遍历打印
test_list = ["张三", 1, True, False, [1,2,3]] # 该list不同于java,不受泛型限制,也可以存入嵌套列表
for i in range(0, len(test_list)):
print(test_list[i]) # 遍历打印
tips:元素下标:
如果是从左往右,则是0开始递增(0,1,2,3…);
如果是从右边开始,则是从-1开始依次往左边递减(…-5,-4,-3,-2,-1)。
在 python 中,如果将函数定义为 class(类)的成员,那么函数会称之为:方法
def add(x, y): class Student:
return x + y def add(self, x, y)
return x + y
函数 方法
-
函数的使用:
num = add(1, 2) -
方法的使用:
student = Student()
num = student.add(1, 2)
1、列表插入元素:
test_list.insert(1, "李四") # 在下标为 1 的位置插入元素
2、追加元素:追加元素是加在末尾
test_list.append("王五")
3、将一个列表添加到新的列表:
test_list = ["张三", 1, True, False, [1,2,3]]
test_list2 = ["李四", "王五"]
test_list.extend(test_list2)
for i in range(0, len(test_list)):
print(test_list[i]) # 遍历打印
4、列表删除元素-语法一:
del test_list[index] # index 为下标
5、列表删除元素-语法二:
test_list.pop(index) # index 为下标
6、删除某个指定的元素:(但是只能删除第一个元素,后续如果有相同的元素需要多次调用 remove 方法)
test_list.remove("张三") # 张三为具体的元素值
7、清空 list 列表:
test_list.clear()
8、统计 list 列表中某个元素值的数量:
test_list.count("张三") # 统计张三这个元素出现的次数
总结:
列表.append(元素) | 向列表中追加一个元素 |
---|---|
列表.extend() | 将数据容器的内容一次取出,追加到列表尾部 |
列表.insert(下标,元素) | 在指定下标处,插入指定的元素 |
del 列表[下标] | 删除列表指定下标元素 |
列表.pop(下标) | 删除列表指定下标元素 |
列表.remove(元素) | 从前往后,删除此元素第一个匹配项 |
列表.clear() | 清空列表 |
列表.count(元素) | 统计此元素在列表中出现的次数 |
列表.index(元素) | 在列表中查找指定元素的下标,找不到就报错 |
len(列表) | 统计容器内有多少元素 |
2、元组(tuple)
元组内的元素不可以被修改。
元组定义:定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型。
# 字面量,里面的元素不受泛型控制
(元素、元素、元素...元素)
# 定义元组变量
变量名称 = (元素、元素、元素...元素)
# 定义空元组
变量名称 = () # 方式一
变量名称 = tuple() # 方式二
如果元组内只有一个元素,需打上一个空的逗号:
# 正确实例
t1 = ("张三", )
# 错误示例
t1 = ("张三")
元组的操作方法:
index() | 查找某个数据,如果存在就返回对应的下标,不存在就报错 |
---|---|
count() | 统计某个数据在当前元组出现的次数 |
len(元组) | 统计元组内的元素个数 |
3、字符串
py 中字符串与 java 相差不大,py 中字符串存在的一个特点就是,字符串下标从左往右是从 0 开始,从右往左是从 -1 开始。
也就是要获取一个字符串最后一个字符,可以这样获取:str[-1]。
tips:字符串中的字符也不支持修改,但是可以使用 replace 替换后赋值给新的一个字符串,旧字符串不变,仅支持查看。
str1 = "hello world"
str2 = str1 .replace("hello", "hi")
print(str1) # hello world
print(str2) # hi world
字符串常用操作:
replace() | 替换子字符串 |
---|---|
splitt() | 将字符串以某个字符分割,存入列表中 |
strip() | 字符串.strip(),去除字符串前后空格 |
strip(“子字符串”) | 去除字符串中子字符串的字符 |
count(“子字符串”) | 统计字符串某个子字符串或字符出现的次数 |
len(“字符串”) | 统计字符串的长度 |
4、序列切片
序列是指:内容连续、有序、可使用下标索引的一类数据容器。列表、字符串、元组均可视为序列。
切片:从一个序列中取出一个子序列。
语法:序列[起始下标:结束下标:步长]
tips:起始下标包含,结束下标不包含。类似于[其实下标,结束下标)。
# 以list举例
list = [1, 2, 3, 4, 5, 6, 7]
print(list[0:4:2]) # [1,3]
print(list[0:4]) # [1,2,3,4],不指定步长默认就是1
print(list[::]) # [1, 2, 3, 4, 5, 6, 7],不写起始,也不写结束、步长,就默认打印全部
print(list[::2]) # [1, 3, 5, 7],末尾的7包含
print(list[::-1]) # [7, 6, 5, 4, 3, 2, 1],步长为-1,表示从倒序打印
5、集合
py 中集合和 java 中类似,无序不重复。
语法:
# 定义集合字面量
{元素,元素,元素,...,元素}
# 定义集合变量
变量名称 = {元素,元素,元素,...,元素}
# 定义空集合
变量名称 = set()
set 集合常用方法:
add(“e”) | 添加新元素 |
---|---|
remove(“e”) | 删除元素 |
pop() | 随机取出一个元素 |
clear() | 清空集合 |
set3 = set1.difference(set2) | 取 set1 和 set2 两个集合的差集,存进 set3 |
set1.difference_update(set2) | 在 set1 内,删除 set2 中相同的元素 |
set3 = set1.union(set2) | 合并 set1 和 set2,存入 set3 |
len() | 统计集合中的元素 |
6、字典
# 定义字典
my_dict = {"王力宏":99, "周杰伦":88, "林俊杰":77...}
# 定义空字典
my_dict2 = {}
my_dict3 = dict()
# 定义嵌套字典
stu_score_dict = {
"王力宏":{"语文":77, "数学":88, "英语": 66},
"周杰伦":{"语文":78, "数学":45, "英语": 90},
"林俊杰":{"语文":82, "数学":33, "英语": 88}
}
取王力宏的语文成绩:score = stu_score_dict[“王力宏”][“语文”]
取王力宏的所有数据:score = stu_score_dict[“王力宏”]
常用操作:
dict = {“张三”:1, “李四”:2, “王五”:3}
dict[“赵六”:4] | 添加新元素(如果存在就是更新操作) |
---|---|
dict.pop(key) | 删除元素 |
dict.clear() | 清空元素 |
dict.keys() | 获取全部 key |
len(dict) | 统计字典内的元素数量 |
7、数据容器总结
----------------- | 列表 | 元组 | 字符串 | 集合 | 字典 |
---|---|---|---|---|---|
元素数量 | 支持多个 | 支持多个 | 支持多个 | 支持多个 | 支持多个 |
元素类型 | 任意 | 任意 | 仅字符 | 任意 | value:任意类型 |
下标索引 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
重复元素 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
可修改性 | 支持 | 不支持 | 不支持 | 支持 | 支持 |
数据有序 | 是 | 是 | 是 | 否 | 否 |
使用场景 | 可修改、可重复的一批数据记录场景 | 不可修改、可重复的一批数据记录场景 | 一串字符的记录场景 | 不可重复的数据记录场景 | 以key检索value的数据记录场景 |
容器通用操作:
-
len():元素个数。
-
max():最大元素。
-
min():最小元素。
-
类型转换:
- 容器转列表: list()
- 容器转元组:tuple()
- 容器转字符串:str()
- 容器转集合:set()
-
容器排序:sorted(容器,reverse=true),统一转为列表对象。
十七、函数相关
- 函数多返回值:
def test_return():
return 1,2
x,y = test_return()
print(x) # 1
print(y) # 2
- 函数传参:
def user_info(name, age, gender):
print(f"您的名字是:{name}, 年龄是:{age}, 性别是:{gender}")
# 关键字传参
user_info(name="张三", age=20, gender="男")
# 可以不安固定顺序传参
user_info(age=20, name="张三", gender="男")
- 缺省参数:缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注:所有位置参数必须出现在默认参数前,包括函数定义和调用)。
def user_info(name, age, gender="男"):
print(f"您的名字是:{name}, 年龄是:{age}, 性别是:{gender}")
user_info(name="张三", age=20)
user_info(name="张三", age=20, gender="女")
-
不定长参数:不定长参数也叫可变参数,用于不确定调用的时候会传递多少个参数的场景(或者不传参)。
- 位置不定长: 不能传递键值对。
注意:传进的所有参数都会被 args 变量收集,它会根据传进参数的位置合并为一个元组(tuple),args 是元组类型,这就是位置传递。
def user_info(*args): print(args) user_info('TOM') # ('张三',) user_info('TOM', 18) # ('张三', 18)
- 关键字传递:必须传递键值对。
def user_info(**kwargs): print(kwargs) user_info(name="张三", age=20, gender="女") # {'name': '张三', 'age': 20, 'gender': '女'}
注意:参数是 key-value 形式的情况下,所有的键-值都会被 kwargs 接收,同时会根据键-值组成字典(dict)。
-
函数中传递函数参数:
def test_fun(compute) # 把函数作为参数传入
result = compute(1,2)
print(result)
def compute(x, y)
return x + y
十八、lambda 匿名函数
def test_fun(compute): # 把函数作为参数传入
result = compute(1, 4)
print(result)
# 对于 compute 函数,采用匿名函数代替
test_fun(lambda x, y: x + y)
十九、文件读取操作
在 python 中,使用 open 函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下:
# name:是要打开的目录文件名的字符串(可以包含文件所在的具体路径)
# mode:设置打开文件的模式:只读、写入、追加等。
# encoding:编码格式(推荐使用 UTF-8)
open(name, mode, encoding)
mode 常用的三种基础访问模式:
- r:以只读方式打开文件,文件的指针将会放在文件的开头,这是默认模式。
- w:打开一个文件只用于写入,如果该文件已存在则打开覆盖内容,如果文件不存在,则创建文件。
- a:打开一个文件用于追加,如果该文件已存在,新的内容将会被写入到已有内容之后,如果该文件不存在,创建新文件进行写入。
1 读文件:
open() 读文件函数常用方法:
- read(num):读取文件,num 表示要读取的数据长度。
- readlines(num):以行的方式对整个文件中的内容进行一次性读取,并且返回一个列表,其中每行数据为一个元素。
- readline():每次读取一行。
示例:
f = open("F:/Study/py/test.txt", "r", encoding="UTF-8")
print(f.readlines()) # 以行读取存入列表
f.close() # 文件关闭
读文件操作总结:
操作 | 功能 |
---|---|
文件对象 = open(file, mode, encoding) | 打开文件获得文件对象 |
文件对象.read(num) | 读取指定长度字节,不指定读取文件全部 |
文件对象.readline() | 读取一行 |
文件对象.readlines() | 读取全部行,得到列表 |
for line in 文件对象 | for 循环文件行,一次循环的到一行数据 |
文件对象.close() | 关闭文件对象 |
with open() as f | 通过with open语法打开文件,可以自动关闭 |
2 写文件:
写文件如果文件不存在,则会新建文件;如果文件存在,则会覆盖所有文件内容。
f = open("F:/Study/py/test.txt", "w", encoding="UTF-8")
f.write("hello world") #
f.flush()
3 追加文件:
追加文件顾名思义,在文件末尾追加内容。但如果文件不存在,则会新建文件;如果文件存在,才在文件末尾追加内容。
f = open("F:/Study/py/test.txt", "a", encoding="UTF-8")
f.write("\nsdfsd sdf sdf ")
f.flush()
二十、异常
与 java 一样,py 也存在异常。
-
捕获异常
基本语法:
try: 可能发生错误的代码 except: 如果出现异常执行的代码
打开一个不存在的文件,捕获异常:
try: f = open("F:/Study/py/test122.txt", "r", encoding="UTF-8") except: print("出现异常了")
-
捕获指定异常:
try: print(name) except NameError as e: print("name变量未定义异常")
-
如捕获多个异常,可以把要捕获的异常类型名字用逗号隔开:(当然也可以捕获全局异常:Exception)
try: 1 / 0 except(NameError, ZeroDivisionError): print("除数为 0 异常")
-
异常 else:
try: print(1) except Exception as e: print("异常~~~") else: print("我是 else,表示没有发生异常")
-
finally:与 java 中的 finally 一样,表示有没有异常都需要执行
try: f = open("F:/Study/py/test.txt", "a", encoding="UTF-8") except NameError as e: print("name变量未定义异常") else: print("没有异常发生") finally: f.close() print("不管有没有发生异常,我都会执行")
二十一、模块
python 模块,是一个 python 文件,以 .py 结尾,模块能定义函数、类和变量,模块里也能包含可执行的代码。python 的模块可以看作是 java 中的 jar包,导入 jar 包后就可以使用该包内封装的方法或函数。
模块在使用前需要先导入,导入语法如下:
[from 模块名] import [模块 | 类 | 变量 | 函数 | *] [as 别名]
常用的组合形式如下:
- import 模块名
- from 模块名 import 类、变量、方法等
- from 模块名 import *
- import 模块名 as 别名
- from 模块名 import 功能名 as 别名
二十二、python 包
-
1、新建包 my_package。
-
2、新建包内模块:my_module1 和 my_module2。
-
3、模块内代码如下:
使用:
from my_package import my_module1 from my_package import my_module2 # 通过 __all__变量,控制 import * # from my_package import * my_module1.info_print1() my_module2.info_print2()
总结:
1 什么是Python的包?
包就是一个文件夹,里面可以存放许多 Python 的模块(代码文件),通过包,在逻辑上将一批模块归为一类,方便使用。
2 init.py 文件的作用?
创建包会默认自动创建的文件,通过这个文件来表示一个文件夹是 Python 的包,而非普通的文件夹。
3_all_变量的作用?
同模块中学习到的是一个作用,控制 import * 能够导入的内容。
- 第三方包:
类似于 java 中 jar 包一样,有很多第三方的包,在 Python 生态中,有非常多的第三方包(非Python官方),可以极大的帮助我们提高开发效率,如:
- 科学计算中常用的:numpy包
- 数据分析中常用的:pandas包
- 大数据计算中常用的:pyspark、apache-flink包
- 图形可视化常用的:matplotlib、pyecharts
- 人工智能常用的:tensorflow 等。
通过 cmd 命令安装第三方包:
pip install 包名称:
eg:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称
二十三、pyecharts 使用
使用之前先了解一下 json。
pyhton 数据喝 json 数据的相互转化:
# 导入模块
import json
# python数据
data = [{"name":"张三", "age":20}, {"name":"李四", "age":22}]
# 通过 json.dumps(data) 方法把 python 数据转化为 json 数据
data = json.dumps(data)
# 如遇中文乱码则可以加上参数:ensure_ascii=False
data = json.dumps(data, ensure_ascii=False)
# 通过 json.loads(data) 方法把 json 数据转化为 python 数据
data = json.loads(data)
# 如遇中文乱码则可以加上参数:ensure_ascii=False
data = json.loads(data, ensure_ascii=False)
pyecharts :可以借助于 pyecharts 做出数据可视化效果图。
- 1、安装 pyecharts
pip install pyecharts
- 2、查看官方画廊,图表案例
https://gallery.pyecharts.org/#/README
pyecharts 入门:
- 基础折线图:
此处先省略 pyecharts 的学习。# 导包,导入 line 功能构建折线图对象 from pyecharts.charts import Line # 得到折线图对象 line = Line() # x坐标 line.add_xaxis(["中国", "美国", "英国"]) # y坐标数据 line.add_yaxis("GDP", [20, 30, 10]) # 生成图表 line.render()
二十四、对象
设计一个学生类:
class Student:
name = None # 姓名
gender = None # 性别
nationality = None # 国籍
native_place = None # 籍贯
age = None # 年龄
创建对象:
stu_1 = Student()
给对象赋值:
stu_1.name = "张三"
stu_1.gender = "男"
stu_1.nationality = "中国"
stu_1.native_place = "广东省"
stu_1.age = 22
- 成员变量-成员方法
class Student:
name = None # 姓名
gender = None # 性别
nationality = None # 国籍
native_place = None # 籍贯
age = None # 年龄
def __init__(self, name, gender, nationality, native_place, age):
self.name = name
self.gender = gender
self.nationality = nationality
self.native_place = native_place
self.age = age
def say_hi(self):
print(f"大家好,我是{self.name}")
stu_1 = Student()
stu_1.init("李四", "男", "中国", "山东省", 30)
# stu_1.name = "张三"
# stu_1.gender = "男"
# stu_1.nationality = "中国"
# stu_1.native_place = "广东省"
# stu_1.age = 22
print(stu_1.nationality)
print(stu_1.say_hi())
self 表示对象本身的意思,只有通过 self,成员方法才能访问类的成员变量。self 出现在形参中,但是不占用参数位置,不用理会。
- python 中构造方法
class Student:
# python 类可以使用:__init__()方法,称之为构造方法。构造方法与 java 语言中一样,因此不用重复讲解。
def __init__(self, name, gender, nationality, native_place, age):
self.name = name
self.gender = gender
self.nationality = nationality
self.native_place = native_place
self.age = age
def say_hi(self):
print(f"大家好,我是{self.name}")
stu_1 = Student()
stu_1.init("李四", "男", "中国", "山东省", 30)
print(stu_1.nationality)
print(stu_1.say_hi())
- python 魔术方法
python 中这些内置的类方法,各有各自特殊的功能,这些内置的方法我们称之为:魔术方法。
python 内置的魔术方法有很多,此处只列举几个常见的:
__ init __:构造方法:stu_1 = Student(“李四”, “男”, “中国”, “山东省”, 20)
__ str __:字符串方法:
__ lt __:小于大于符号比较:stu_1.age.lt(stu_2.age),前者是否小于后者
__ le __:小于等于、大于等于符号比较
__ eq __:== 符号比较
- python 私有成员变量和私有成员方法
私有的变量和方法必须以 __ 开头。
class Phone:
__is_5G_enable = False # 私有方法,5G状态
# 私有成员方法
def __check_5g(self):
if self.__is_5G_enable:
print("5g")
else:
print("5g关闭,使用4g网络")
# 共有成员方法
def call_by_5g(self):
self.__check_5g()
print("正在通话中")
phone = Phone()
phone.call_by_5g()
- python 继承
语法:
class 类名(父类名):
类内容体
父类:
class Phone:
IMEI = None # 序列号
producer = None # 厂商
def call_by_4g(self):
print("4g通话")
class RemoteControl:
rc_type = "红外遥控"
def control(self):
print("红外严控开启了")
单继承案例:
class Phone2022(Phone): # Phone2022(Phone),括号中的 Phone 表示继承 Phone 类
face_id = True # 面部识别
def call_by_5g(self):
print("2022最新5g通话")
多继承案例:
# 多继承只需要在括号中以逗号隔开
class Phone2022(Phone, RemoteControl):
face_id = True # 面部识别
def call_by_5g(self):
print("2022最新5g通话")
如果不需要额外的自定义方法,可以使用 pass 省略,以满足代码的语法不产生错误:
# 多继承只需要在括号中以逗号隔开
class Phone2024(Phone, RemoteControl):
pass
二十五、多态
多态即多种形态,与 java 语言的多态一致。
多态作用在继承关系上,通常是父类声明定义,子类做实际工作,多态类似于是一个标准,具体的实现靠子类去实现。
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
print("汪汪汪")
class Cat(Animal):
def speak(self):
print("喵喵喵")
二十六、python 操作 mysql
在 python 中,使用第三方库:pymysql 来完成对 mysql 数据库的操作。
安装:
pip install pymysql
创建到 mysql 的数据库连接:
from pymysql import Connection
# 获取 mysql 数据库的连接对象
conn = Connection(
host='localhost',
port=3306,
user='root',
password='123456'
)
print(conn.get_server_info())
conn.close()
模拟读取文件批量插入数据:
from pymysql import Connection
# 定义 Record 类
class Record:
def __init__(self, order_date, order_id, money, province):
self.order_date = order_date
self.order_id = order_id
self.money = money
self.province = province
# 读取文件
class FileReader:
def read_data(self) -> list[Record]:
"""读取文件的数据,读到的每一条数据都转换为Record对象,将它们都封装到list内返回即可"""
pass
# 继承FileReader详细处理文件
class TextFileReader(FileReader):
def __init__(self, file_path):
self.file_path = file_path # 定义成员变量记录文件的路径
# 复写(实现抽象方法)父类的方法
def read_data(self) -> list[Record]:
f = open(self.file_path, "r", encoding="UTF-8")
record_list: list[Record] = []
for line in f.readlines():
line = line.strip() # 消除读取到的每一行数据中的\n
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
# 传入路径,读取数据,存入all_data
all_data: list[Record] = TextFileReader("F:/Study/py/2011年1月销售数据.txt").read_data()
# 获取 mysql 数据库的连接对象
conn = Connection(
host='localhost',
port=3306,
user='root',
password='123456',
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.order_date}', '{record.order_id}', {record.money}, '{record.province}')"
# 执行 SQL语句
cursor.execute(sql)
# 关闭连接
conn.close()
文件中数据格式:
批量插入数据表中截图:
二十七、闭包
- 什么是闭包?
闭包(Closure)指的是一个函数中包含了对其外部函数自由变量的引用。如下代码示例,假如我们做存取款操作,那么金额 account_amount 变量就是一个全局变量,存在被修改的风险。
account_amount = 0
def atm(num, deposit=True):
global initial_amount
if deposit:
account_amount += num
print(f"存款:+{num},账户余额:{account_amount }")
else:
account_amount -= num
print(f"存款:-{num},账户余额:{account_amount }")
对于闭包,再做如下解释:
在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包。
- 改用闭包的形式改造上述代码:
def account_create(initial_amount=0):
def atm(num, deposit=True):
# 使用 nonlocal 关键字修改外部函数变量的值,否则无法修改。
nonlocal initial_amount
if deposit:
initial_amount += num
print(f"存款:+{num},账户余额:{initial_amount}")
else:
initial_amount -= num
print(f"存款:-{num},账户余额:{initial_amount}")
return atm
atm = account_create()
atm(100)
atm(100)
atm(100, deposit=False)