“”"
1.安装软件
2.环境变量的配置
变量名 变量值
Path 应用程序所在的路径(可执行的应用程序 xxx.exe 所在的文件夹)
3.DOS常用命令的使用
3.1 盘符切换
盘符:
3.2 进入文件夹
cd 路径
3.3 展示文件夹
dir
tree
3.4 清除屏幕
cls
3.5 自动补全名称
tab
4.变量
定义(在定义时,要给出初始值) 初始化
重新赋值
5.标识符(变量名)
要求:
可以有字母(包含中文),数字,下划线
数字不能开头,不能为系统的关键字,大小写敏感
关键字(保留字/敏感字)
35个
查看方式:
import keyword
print(keyword.kwlist)
如何更好的命名:
1.见名知意
2.驼峰命名法
大驼峰 MaxValue
小驼峰 maxValue
下划线连接 max_value
python中的数据类型:
数值类型:bool,int,float,complex
字符串:str
复合类型:list,tuple,dict,set
运算符:
优先级以及结合性
数学运算符
+
-
*
/
//
%
**
赋值运算符
简单的赋值
a = 1
复合的赋值
+=
-=
*=
/=
%=
**=
//=
a %= b ==>>> a = a % b
比较运算符
操作数(一般情况下,要求类型一致),比较结果(bool)
>
<
>=
<=
==
!=
age = 10
8 < age < 100
逻辑运算符
and
要求两个条件都满足,结果为True
or
要求两个条件有一个满足,整个结果就为True
not
如果条件为真,加上not 就变成假
“”"
a = 0
v = ‘a’ > 10 # TypeError: ‘>’ not supported between instances of ‘str’ and ‘int’
print(v)
“”"
数值类型之间类型转换:
1.强制转换
由高到低的转换,需要强制转换
2.自动转换
由低到高这时候的类型转换属于自动转换
bool < int < float < complex
bool
int
float
complex
其他类型之间的转换:
常用的转换功能:
int() 转换为整数
float() 转换为小数
str() 转换为字符串
chr()
将unicode编码值 转换为其对应的字符串
ord()
得到字符串对应的unicode编码值
两个函数可以实现互逆操作
eval()
将字符串转数字的时候,会根据字符串是整型,还是小数来进行自动匹配
list()
tuple()
set()
“”"
# # 自动转换
# x = True
# a = 1
# b = 2.5
# c = a + b
# print(type(c))
# print('---------------')
# d = x + a
# print(type(d))
# print('---------------')
# e = x + b
# print(type(e))
# print('---------------')
# # 复数 实部+虚部
# y = 2 + 3j
# print(type(y))
# z = a + y
# print('--------======')
# print(type(z))
# print(z)
#
# print('**'*30)
# # 强制转换
# g = int(b)
# print(type(g))
# h = bool(b)
# print(type(h))
# ch = chr(20002)
# ch = chr(65)
# ch = chr(97)
# print(ch)
# print(type(ch))
# v = ord('宋')
# v = ord('A')
# print(v)
# str1 = '123'
# str1 = '123.5'
str1 = '[1,2,3]'
# 将字符串转换为整数
# v1 = int(str1)
# v1 = float(str1)
v1 = eval(str1)
print(v1)
print(type(v1))
“”"
\n 换行
输出:
print(要输出的内容)
换行的控制问题
print(‘xxx’,end = ‘’)
格式化的输出:
print('name:%s age:%i')
%s:表示字符串
%i/%d:表示整型
%f:表示小数,默认保留小数点后6位,最后一位四舍五入
%g: 可以表示整数,也可以保留小数,如果是小数处理的时候,只保留认为有意义的数据
输入:
v = input(‘输入提示’)
不论输入的是什么类型的数值,变量v接收到的值,都是str类型
“”"
# name = '小明'
# age = 18
# tel = 13800000000
# print('我叫%s,今年%i岁 手机号:%s,风华正茂,玉树临风'%(name, age, tel), end='\n')
# print('我叫%s,今年%i岁,风华正茂,玉树临风'%(name, age), end='\n')
# print(f'我叫{name},今天{age}岁,手机号:{tel},风华正茂,玉树临风',end='\n')
#
# a = 10
# print('a = %f'%a)
# print('a = %.2f'%a)
#
# PI = 3.1415925535897
# print('PI=%f'%PI)
#
# # b = 2.50000000
# # b = 2.511111111111
# b = 10.0
# print('b=%g'%b)
# name = input('请输入你的姓名')
# print(type(name))
# print(name)
# age = input('请输入你的年龄')
# print(type(age))
# print(age)
需求:从键盘输入两个变量a,b,求和,并打印
a = input('请输入变量a的值')
b = input('请输入变量b的值')
c = int(a) + int(b)
print(type(c))
print(f'和为:{c}')
“”"
变量 组词
语句 造句
函数 一段作文
类 整篇文章
语句结构:
顺序结构
从上往下,从左往右,依次执行
分支结构
案例练习:
未成年人上网 (网咖)
骰子大小 1-6 [1-3] [4-6]
随机模块的使用
import random
n = random.randint(a,b)# 生成a-b之间的随机数,包含a跟b
用户登录
默认注册好的用户名
acc = ‘abc’
pw = ‘123’
输入用户名,输入密码
if 用户名对 同时 密码也对:
登录成功
判断结构(向左走,向右走)
1.单分支
2.双分支
3.多分支
循环结构
重复(鬼打墙)
“”"
顺序结构
# print('HelloWorld1')
# print('HelloWorld2')
# print('HelloWorld3')
从键盘你的年龄,根据年龄来判断是否可以上网
# age = input('请输入你的年龄')
# # 数据类型转换的问题
# age = int(age)
# if 18 <= age <= 100:
# # if age >= 18 and age <= 100:
# print('xx网咖欢迎您')
#
# if age < 18 or age > 100:
# print('回家洗洗睡')
需求:生成随机数,判断大小问题
import random
n = random.randint(1,6)# 1 <= n <= 6
print(n)
if 1 <= n <= 3:
print('小')
if 4 <= n <= 6:
print('大')
“”"
注册用户名,密码
输入用户名,密码,完成校验登录
双分支语法:
if 条件:
条件成立执行的代码
else:
条件不成立执行的代码
需求:根据年龄上网问题: 改成双分支的判断形式
需求:骰子点数大小问题,改成双分支的判断形式
“”"
注册
usename_register = input('请输入注册的用户名:')
password_register = input('请输入注册的密码:')
# 验证登录
username_login = input('请输入之前注册的用户名:')
password_login = input('请输入之前注册的密码')
# 登录校验-登录成功 and
if username_login == usename_register and password_login == password_register:
print('登录成功')
else:
print('登录失败')
# 登录校验-登录失败 (1.用户名不对,密码对 2.用户名对,密码不对 3.都不会)
# if (username_login != usename_register and password_login == password_register) or (username_login == usename_register and password_login != password_register) or (username_login != usename_register and password_login != password_register):
# print('用户名/密码有误')
“”"
双分支结构:
点数大小问题
三元条件表达式:
“”"
import random
n = random.randint(1, 6)
# if 1 <= n <= 3:
# result = '小'
# else:
# result = '大'
# 三元条件表达式
result = '小' if 1 <= n <= 3 else '大'
print(result)
“”"
分支结构:
1.单分支
if 条件:
条件成立执行的代码
2.双分支
if 条件:
条件成立执行的代码
else:
条件不成立执行的代码
3.多分支
if 条件1:
条件1满足执行
elif 条件2:
条件2满足执行
elif 条件3:
条件3满足执行
…
else:
其他情况
需求:
根据你考试的分数,给出对应的评级
A:[90,100]
B:[80,90)
C:[70,80)
D:[60,70)
E: < 60
需求: 输入一个月份,打印对应的季节
“”"
score = input(‘请输入你考试的分数:’)
自动转换
score = eval(score)
if 90 <= score <= 100:
print('A')
elif 80 <= score < 90:
print('B')
elif 70 <= score < 80:
print('C')
elif 60 <= score < 70:
print('D')
elif 0 <= score < 60:
print('E')
else:
print('分数有误')
“”"
需求: 输入一个月份,打印对应的季节
1.输入 input()
2.类型转换
3.多分支
春:
3-5
夏:
6-8
秋:
9-11
冬:
12,1,2
“”"
month = input('请输入一个月份1-12:')
month = int(month)
if 3 <= month <= 5:
print('春天')
elif 6 <= month <= 8:
print('夏天')
elif 9 <= month <= 11:
print('秋天')
***# elif month == 12 or month == 1 or month == 2:***
elif month == 12 or 1 <= month <= 2:
print('冬天')
else:
print('输入有误')
“”"
分支的嵌套使用
if 外部条件:
外部条件成立
if 内部条件:
内部条件成立
else:
内部条件不成立
else:
外部条件不成立
生活案例:
if 有车票:
进站安检
if 安检合格:
可以进站候车
else:
安检不合格无法进站
else:
无法进入安检
开发过程中的使用:
“”"
“”"
骰子点数大小问题:
猜(输入)
你猜的结果跟开奖的结果做比较,中还是没中
1.先猜
2.摇点数
3.开奖
需求:
输入用户名密码
if 用户名密码都正确:
直接打印出模拟生成验证码:
if 验证码是否正确:
登录成功
else:
验证码有误
else:
用户名或密码有误
“”"
i
mport random
# 猜的点数
result_guess = input('请猜大/小:')
# 生成随机点数
n = random.randint(1, 6)
# 比较处理
if result_guess == '大':
if 4 <= n <= 6:
print(f'恭喜中奖:猜的大,开的{n}')
else:
print('很遗憾,猜的大,开的小')
else:
if 4 <= n <= 6:
print('很遗憾,猜的小,开的大')
else:
print(f'恭喜中奖,猜的小,开的{n}')
“”"
需求:
输入用户名密码
if 用户名密码都正确:
直接打印出模拟生成验证码:
if 验证码是否正确:
登录成功
else:
验证码有误
else:
用户名或密码有误
“”"
import random
usename_register = 'abc'
password_register = '123'
# 验证登录
username_login = input('请输入之前注册的用户名:')
password_login = input('请输入之前注册的密码')
***if username_login == usename_register and password_login == password_register:***
# 接入短信接口,可以实现为手机号发送短信
rand_code = random.randint(1000,9999)
rand_code = str(rand_code)
print(rand_code)
code_input = input('请输入你接到到的验证码')
if rand_code == code_input:
print('登录成功')
else:
print('验证码有误')
else:
print('用户名/密码有误')
“”"
1.顺序结构
2.分支结构
3.循环结构
重复
while
语法:
while 条件:
条件成立执行(执行完毕之后,会继续判断条件)
死循环:
while True:
while 1 < 2:
执行
案例:
打印10次HelloWorld
练习:
打印1-100之间所有的偶数
for
“”"
# print('HelloWorld')
# print('HelloWorld')
# print('HelloWorld')
# i = 1
# while i <= 10:
# print(f'HelloWorld{i}')
# i = i + 1
想打印1-100之间的数字
# i = 1
# while i <= 100:
# print(i)
# i += 1
# i = 0
# while i <= 100:
# print(i)
# i += 2
打印10-1所有的数字
# i = 10
# while i >= 1:
# print(i)
# i -= 1
“”"
1.数据类型的转换
自动转换
由低到高自动转换
bool->int->float->complex
强制转换
不同的数值类型之间,由高到低,需要强制转换
不同的数据类型之间,需要强制转换
int()
float()
str()
bool()
---------
list()
set()
dict()
tuple()
----------
chr(code)
ord()
---------
eval()
1.根据字符串类型自动转换对应的数值类型
2.将字符串表达式转换为实际表达式并进行运算,得出运算结果
2.输出
print(‘xxx’)
格式化输出:
%s
%i/%d
%f
%g
name = ‘xx’
age = 18
print(‘我叫%s,今年%i’%(name,age),end=’’)
print(f’我叫{name},今年{age}’)
print(f’我叫{“小明”}’)
3.输入
v = input(‘输入提示’)
不论输入的是什么内容,v都是以字符串的形式存在的
4.语句结构
顺序结构
从上往下,从左往右依次执行
分支结构
判断,选择
单分支
if 条件:
条件成立执行
双分支
if 条件:
条件成立执行
else:
条件不成立执行
多分支
if 条件1:
条件1成立执行
elif 条件2:
条件2成立执行
...
else:
除以上条件之外,会执行
循环结构
判断,重复
while 条件:
条件成立执行
让条件趋向终止
“”"
# v = input('请输入一个整数或小数')
# print(type(v))
# print(v)
# print('---'*20)
# v = eval(v)
# print(type(v))
# print(v)
print(f'我叫{"小明"}')
“”"
1.输入一个考试分数,判断考试结果是否为通过,如果分数>= 60,通过,
否则,结果为不通过(分别使用双分支,以及三元条件表达式)
“”"
# score = input('请输入你的考试分数')
# score = eval(score)
# v = '通过'if score >= 60 else '不通过'
# print(v)
“”"
3.循环输入5个100以内的正整数,打印出输入的最大值,最小值,总和
“”"
max_value = 0
min_value = 100
sum = 0
i = 1
while i <= 5:
n = int(input(f'请输入第{i}个100以内的整数'))
if n > max_value:
max_value = n
if n < min_value:
min_value = n
# 将输入的数字累加到变量sum中
# sum = sum + n
sum += n
print(f'当前的最大值为:{max_value}')
print(f'当前的最小值为:{min_value}')
i += 1
print(f'最终的最大值为:{max_value}')
print(f'最终的最小值为:{min_value}')
print(f'所有数字的和为:{sum}')
“”"
5.使用一个循环打印出所有的英文字母(大小写)
A-Z
65-90
a-z
97-122
chr()
“”"
# i = 65
# while i <= 90:
# print(chr(i),end=' ')
# print(chr(i+32),end=' ')
# i += 1
“”"
6.打印以下数列 1/3 , 2/5 ,3/7 , 4/9…前10项,并求出总和
“”"
# i = 1
# while i <= 10:
# j = 2 * i + 1
# print(f'{i}/{j}',end=',')
# i += 1
# for i in range(10):
# j=2*i+1
# print(f'{i}/{j}',end=',')
“”"
7.使用循环如下图形:
*
**
“”"
# for i in range(1,6):
# print('*'*i)
# i = 1
# while i <= 5:
# # * 可以实现字符串的重复
# print('*'*i)
# i += 1
# print('--'*20)
“”"
8.猜拳游戏(玩10次):
while 终止条件:
cmp = 计算机随机生成(0,2) #0.石头 1.剪刀 2.布
you = 输入(0.石头 1.剪刀 2.布)
if 计算机获胜的情况:
print(计算机得1分)
elif 平局:
print(‘平局’)
else:
print(‘你得1分’)
print(统计结果)
“”"
import random
# 记录你赢的次数
a = 0
# 计算机赢的次数
b = 0
# 平局次数
c = 0
i = 1
while i <= 10:
cmp = random.randint(0,2)
you = int(input('计算机思考完毕,该你了:0-石头 1-剪刀 2-布'))
# 比输赢(1.从用户的输赢的角度来考虑 2.可以从用户出的什么角度来考虑)
***if (you == 0 and cmp == 1) or (you == 1 and cmp == 2) or (you == 2 and cmp == 0):***
print('you win!')
a += 1
elif you == cmp:
print('平局')
c += 1
else:
print('you lose!')
b += 1
i += 1
else:
# 与while循环结合使用的else 会在循环正常结束后执行
print(f'你获胜{a}次,平局{c}次,输了{b}次,胜率{a/10*100}%')
“”"
循环结构:
while循环
语法:
while 条件:
循环体
条件趋向终止
for循环
语法:
for 变量 in range():
循环体
range(stop)
range(start,stop,step)
start:表示起点,可以不写,默认从0开始
stop:表示终点(但是不包含终点这个数)
step:表示的步长,默认为1
循环控制的关键字
break:
结束当前循环
continue
跳过本次循环
for
pass
else
pass
“”"
打印1-5的整型数字
# i = 1
# while i <= 5:
# print(i,end=' ')
# i += 1
# for i in range(100,0,-22):
# if i>=36:
# continue
# if i==22:
# continue
# if i==8:
# break
# print(i,end='\t')
# for i in range(1,6,1):
# print(i,end=' ')
# 不写步长,默认为1
# for i in range(1,6):
# print(i,end=' ')
# 不写起点,默认从0开始
# for i in range(6):
# print(i,end=' ')
# i = 5
# while i > 0:
# print(i,end=' ')
# i -= 1
# print(f'while循环已经结束,i={i}')
# list1=[111,2,3,4,555,3,2,121]
# list2=list1[-1:-3:-1]
# print(list2)
#
# print('-------------------------')
#
# for i in range(5,0,-1):
# print(i,end=' ')
# print(f'循环已经结束,i={i}')
使用for循环打印100以内的偶数
# for i in range(2,101,2):
# print(i,end=' ')
循环生成10以内的随机数字,直到生成8结束(循环次数未知)
# import random
# n = 0
# i = 0
# while n != 8:
# n = random.randint(1,10)
# i += 1
# print(f'第{i}次生成的随机数字为{n}')
break 与 continue的使用
# for i in range(10):
# if i == 5:
# # break
# continue
# print(i,end=' ')
for-else的使用
# for i in range(10):
# if i == 5:
# break
# # if i == 9:
# # continue
# print(i,end=' ')
# else:
# print('循环正常结束')
# print('循环结束')
“”"
嵌套分支:
嵌套循环:
外循环
内循环
while
while
while
for
for
for
for
while
执行:
外循环执行一次,内循环从头到尾执行一遍
“”"
# for i in range(5):
# print(f'外循环,i = {i}')
# for j in range(5):
# print(f'内循环,j = {j}')
# i = 0
# while i < 5:
# print(f'i = {i}')
# j = 0
# while j < 5:
# print(f'j={j}')
# j += 1
# i += 1
嵌套循环中的break
break 结束所在的循环
# end = False
# for i in range(5):
# print(f'外循环,i = {i}')
# if end:
# break
# for j in range(5):
# if j == 2:
# end = True
# break
# print(f'j = {j}')
# for i in range(1,11):
# if i%2==0:
# continue
# for j in range(11-i):
# if j%2==1:
# continue
# for k in range(2*i-1):
# print(i,end='\t')
# print()
***# for i in range(100,200,2):***
***# if i%3==0 and i%7!=0 or i%7==0 and i%3!=0:***
***# for j in range(200-i):***
***# continue***
***# print(i,end='\t')***
“”"
使用嵌套循环,打印矩阵时,外循环控制行,内循环控制列
**
“”"
# print('*****')
# print('*'*5)
# count1 = 5
# count0 = 6
# count1 = 8
# for j in range(count0):
# for i in range(count1):
# print('*', end=' ')
# else:
# print()
***# for i in range(1,10):
# # 每一行中的内容
# for j in range(i):
# print('? * ? = ?',end=' ')
# print()***
# for i in range(5):
# for j in range(i+1):
# print('*',end='')
# print()
# a=5
# b=6
***# for i in range(a):***
***# for j in range(b):***
***# if i==0 or j==b-1 or j==0 or i==a-1:***
***# print('*',end='\t')***
***# else:***
***# print('',end='\t')***
# print()
# a=5
# for i in range(a):
# for j in range(a-i):
# print('*',end='\t')
# print()
#运行后
*****
****
***
**
*
打印菱形
# *
# ***
# *****
# *******
# *********
# *******
# *****
# ***
# *
for i in range(1,5):
for j in range(5-i):
print(’ ‘,end=’’)
for k in range(2*i-1):
print(’*’,end=’’)
print()
for i in range(5,0,-1):
for j in range(5-i):
print(’ ‘,end=’’)
for k in range(2*i-1):
print(’*’,end=’’)
print()
for i in range(1,4):
for j in range(4-i):
print(’ ‘,end=’’)
for k in range(2i-1):
print(’’,end=’’)
print()
for i in range(4,0,-1):
for j in range(4-i):
print(’ ‘,end=’’)
for k in range(2i-1):
print(’’,end=’’)
print()
# for i in range(1,10):
# # 每一行中的内容
# for j in range(i):
*# print(f’{j+1} * {i} = {(j+1)i}’,end=’\t’)
# print()
“”"
打印空心矩阵
-
*
-
*
-
*
-
*
打印等腰三角形
*
“”"
count0 = 10
count1 = 15
for j in range(count0):
for i in range(count1):
# 如果是第一行或者最后一行第一列或者最后一列 j控制行 i控制列
# if j == 0 or j == count0-1 or i == 0 or i == count1-1:
print(’*’, end=’ ')
else:
print(’ ‘,end=’ ')
else:
print()
打印等腰三角形
for i in range(1,5):
# 打印‘ ’
for k in range(5-i):
print(’ ‘,end=’’)
# 打印*
for j in range(2*i-1):
print(’*’,end=’’)
print()
“”"
练习 打印1-100之间所有数字,按指定的要求的分行
分行示例如下:
1
2 3
4 5 6
7 8 9 10
…
“”"
# 用来几个数字进行换行
count = 1
# 计数器
count2 = 0
for i in range(1,101):
print(i,end=’\t’)
count2 += 1
if count2 == count:
print()
# 每换行一次,控制换行的个数+1
count += 1
# 计数器清0,保证下次从头开始数
count2 = 0
a=1
a1=0
for i in range(2,101,2):
print(i,end=’\t’)
a1+=1
if a1==a:
print()
a+=1
a1=0
a2=1
a3=0
for i in range(100,0,-1):
print(i,end=’\t’)
a3+=1
if a3==a2:
print()
a2+=1
a3=0
“”"
列表(list)
可以存储多个任意类型的数据
引入
存储某个学生的信息
名字 年龄 性别
定义
stu_info = []
内存结构
栈上存地址
堆上存数据
求列表长度(列表中元素的个数)
len(list)
列表特点:
可以重复,有序
索引问题
可以访问列表中的具体元素
list[index]
注意:
索引越界问题
IndexError
索引范围:
【0,len(list)-1】
序列操作
相加
重复
切片
遍历
序列解包
多个变量名来接收元素
“”"
定义
stu0_info = [‘王铁锤’,18,‘女’,170,98]
通过系统提供的功能添加元素
stu0_info.append(1001)
print(type(stu0_info))
print(f’列表stu0_info的内存地址为:{id(stu0_info)}’)
stu1_info = stu0_info
print(f’列表stu1_info的内存地址为:{id(stu1_info)}’)
print(f’名称:{stu0_info[0]}’)
IndexError: list index out of range
print(stu0_info[5])
stu1_info[2] = ‘男’
print(stu1_info)
print(stu0_info)
list1 = [1,2]
list2 = [2,3]
list3 = list1 + list2
print(list3)
可以通过* 完成列表的重复创建
list4 = list1 * 2
print(list4)
print(’–’*30)
列表中元素的遍历(打印列表中所有的元素)
i = 0
while i < len(stu0_info):
print(stu0_info[i])
i += 1
for i in range(len(stu0_info)):
print(stu0_info[i])
for 变量 in 列表:
for i in stu0_info:
print(i)
“”"
1.for循环
for 变量 in range():
pass
range(stop)
range(start,stop,step)
start: 表示开始
默认为0
stop: 表示结束
step: 表示步长
默认步长为1
步长可以为负数,表示递减
for
else:
循环正常结束会执行的代码
break:
结束当前循环
continue:
表示跳过本次循环
2.嵌套循环
外循环
内循环
执行顺序:
外循环执行一次,内循环从头到尾执行一遍
3.列表的基本使用
list
概念:
可以存储任意多个不同类型的数据
定义:
list1 = []
特点:
有序,元素可以重复
内存:
两块内存,栈上存地址(引用),堆上存数据
长度:
len(list)
访问元素:
通过索引值
list[index]
索引范围
[0,len(list)-1]
拼接:
v = [1,2]+[3,4]
重复:
v = [1,2]*2
尾部添加:
list.append(e)
“”"
l0 = [1,1,1,4,5,6,7]
l = [1,2,3,4,5,6,7]
for i in range(len(l)-3):
l1 = l[i:i+4]
if l1 == l0[i:i+4]:
print(f’中出号码为{l1}’)
break
print(l1)
“”"
1.从键盘录入行为5,列为5,打印如下图形:
-
*
-
*
-
*
“”"
a = int(input(‘请输入行’))
b = int(input(‘请输入列’))
for i in range(a):
for j in range(b):
# if i == 0 or i == a-1 or j == 0 or j == b-1:
print(’*’,end=’ ')
else:
print(’ ‘,end=’ ')
print()
“”"
2.循环生成10个100以内的随机数,存储到列表中,找出最大值,最小值
“”"
import random
# 定义一个列表,用来存储所有的数据
nums_list = []
for i in range(10):
n = random.randint(1,100)
nums_list.append(n)
print(’–’*20)
print(nums_list)
假设列表中的最大值为第一个元素
max_value = nums_list[0]
# 假设列表中的最小值为第一个元素
min_value = nums_list[0]
循环将当前最大值与其他数据一次比较,找出最大的,最小的
for i in range(1,len(nums_list)):
if max_value < nums_list[i]:
max_value = nums_list[i]
if min_value > nums_list[i]:
min_value = nums_list[i]
调用系统功能直接实现:
max_value = max(nums_list)
min_value = min(nums_list)
print(f’{nums_list}中最大值为:{max_value} 最小值为:{min_value}’)
“”"
3.生成一个长度为4的验证码,存储到列表中,要求前两个为小写字母,后两个为0-9之间的数字
“”"
import random
code_list = []
for i in range(4):
if i < 2:
# 生成对应的随机数,使用chr转换为字母
code = chr(random.randint(97,122))
code_list.append(code)
else:
n = str(random.randint(0,9))
code_list.append(n)
print(code_list)
“”"
斐波那契数列
4.有一个数列(例如:1,1,2,3,5,8,13…),使用循环求出数列的第n个数,n为从键盘录入的
“”"
n = int(input(‘请输入要求的第几个数’))
使用循环实现
a = 1
b = 1
i = 3
while i <= n:
a, b = b, a + b
print(b,end=’\t’)
i += 1
使用列表实现
list1 = [1,1]
i = 3
while i <= n:
list1.append(list1[-2]+list1[-1])
i += 1
print(list1[n-1])
import sys
print(sys.getsizeof(list1))
“”"
5.从键盘录入一个数字,找出这个数字的所有约数,存储到列表中
约束: 能被整除的数
“”"
nums_list = []
n = int(input(‘请输入一个数字’))
for i in range(1,n+1):
# 判断n是否能被i整除
if n % i == 0:
nums_list.append(i)
print(nums_list)
“”"
6.录入两个数字,找出两个数字的最大公约数
“”"
a = int(input(‘请输入一个整数’))
b = int(input(‘请输入另外一个整数’))
存储a的所有约数
nums_list1 = []
存储b的所有约数
nums_list2 = []
求出a的所有约数
for i in range(1,a+1):
if a % i == 0:
nums_list1.append(i)
求出b的所有约数
for i in range(1,b+1):
if b % i == 0:
nums_list2.append(i)
print(nums_list1)
print(nums_list2)
遍历其中一个列表的数据(从后往前进行遍历)
for i in range(len(nums_list1)-1,-1,-1):
# 如果这个约数在另外一个列表
if nums_list1[i] in nums_list2:
print(f’最大公约数:{nums_list1[i]}’)
# 找到之后直接结束
break
“”"
7.模拟随机生成一组福利彩票10选3的号码(不能有重号)
1-10的号码选3个数
“”"
import random
nums_list = []
while len(nums_list) < 3:
n = random.randint(1,10)
if n not in nums_list:
nums_list.append(n)
print(nums_list)
“”"
8.手动选择一组号码,存储到列表中(不能有重号,如果输入的为重号,则提示重新输入)
“”"
nums_list1 = []
while len(nums_list1) < 3:
n = int(input(‘请输入1-10之间的任意数字’))
if n not in nums_list1:
nums_list1.append(n)
else:
print(‘号码重复,重新输入’)
else:
print(f’你输入的号码为:{nums_list1}’)
“”"
9.统计出两组号码(手选号码与随机号码)中的相同号码,存储到新列表中
“”"
遍历其中一个列表,看这个列表中的元素是否在另外一个列表中,如果在,添加到新列表中
nums_list2 = []
for n in nums_list:
if n in nums_list1:
nums_list2.append(n)
使用嵌套循环 找出两个列表中相同的元素
nums_list2 = []
for n in nums_list:
for m in nums_list1:
if n == m:
nums_list2.append(n)
break
print(f’相同号码为:{nums_list2}’)
“”"
列表的切片:
意义:
可以基于一个列表,通过切片操作,得到一个新的列表
注意:
基于索引值操作
语法:
list[start:stop:step]
start:
表示切片的开始位置
可以省略不写,如果不写,默认从头开始
stop:
表示切片的结束位置(不包含终点)
可以省略不写,如果不写,默认到最后(包含最后一个)
step:
步长
可以省略,如果不写,默认值为1
“”"
char_list = [‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘g’]
切片出前三个
sub_list1 = char_list[0:3]
sub_list1 = char_list[0:3:1]
sub_list1 = char_list[:3]
print(type(sub_list1))
print(sub_list1)
切出最后三个
sub_list2 = char_list[4:6]
切片操作中,不存在越界问题
sub_list2 = char_list[4:7]
sub_list2 = char_list[4:700]
sub_list2 = char_list[4:]
sub_list2 = char_list[len(char_list)-3:]
print(char_list[-3:])
print(sub_list2)
print(’—’*20)
步长的问题
sub_list3 = char_list[0::]
sub_list3 = char_list[::2]
print(sub_list3)
print(’----’*20)
步长为负数的问题:
sub_list4 = char_list[3:0:-1]# a b c d e f g
print(sub_list4)
快速得到一个倒序的列表
sub_list5 = char_list[::-1]
print(sub_list5)
“”"
操作列表的常用功能
添加元素
append(obj)
尾部条件元素
insert(index,obj)
指定位置插入指定元素
待验证效率问题
extend(list)
将一个列表中的所有元素,逐个加入到列表一个列表
删除元素
list.remove(要删除的元素)
del list[index]
list.pop(index)
list.clear()
查询元素
修改元素
“”"
list1 = [1,2]
list1.append(3)
print(list1)
list1.insert(0,4)
print(list1)
list2 = [7,8]
将列表2中的所有元素追加到列表1中
list1.extend(list2)
print(list1)#[4, 1, 2, 3, 7, 8]
基于两个列表中的数据,创建一个新的列表
list3 = list1 + list2
list1.remove(8)
print(list1)# [4, 1, 2, 3, 7]
list1.pop(0)
print(list1)# [1, 2, 3, 7]
del list1[0]
print(list1)# [ 2, 3, 7]
list1.clear()
print(list1)# []
“”"
查询
value in list
列表是否包含目标元素
value not in list
列表中是否不包含目标元素
index(obj)
查看目标元素在列表中首次出现的索引值,如果没有,报错
count(obj)
查看目标元素出现的次数
修改
赋值:
list[index] = value
翻转:
list.reverse()
将列表翻转(对源数据操作)
reversed(list)
得到一个翻转的新列表
排序:
list.sort()
按自然顺序(对源数据排序)
list.sort(reverse=True)
按从大到小顺序排序
sorted(list)
按自然顺序排序(得到一个排序后的新列表,源数据不变)
“”"
查找操作
list1 = [1,2,3,4,3,3,3,3]
v = 1 in list1
# v = 1 not in list1
print(v)
i = list1.index(3)
# i = list1.index(100)# ValueError: 100 is not in list
print(i)
# j = list1.count(3)
j = list1.count(100)
print(j)
修改操作
list1 = [1,10,2,4,3,0]
list1[0] = 100
将元素1修改为100(1、是否有该元素 2、找索引 3、按索引修改)
if 1 in list1:
i = list1.index(1)
list1[i] = 100
翻转
list1.reverse()
print(list1)
list2 = reversed(list1)
print(list1)
for i in list2:
print(i)
排序
list1.sort(reverse=True)# 对源数据进行排序
print(list1)
得到一个排序后新列表,源数据不变
list2 = sorted(list1)
print(list1)
print(list2)
“”"
嵌套列表
可以存储任意多个不同数据类型的集合(有序序列)
# 使用列表存储一个学生的信息
stu = [‘xxx’,18,‘男’]
students = [[‘xxx’,18,‘男’],[‘xxx’,18,‘女’],[‘xxx’,18,‘男’]]
嵌套列表中元素的访问:
list1[][]
嵌套列表的内存结构:
list1 = [[1,2],[3,4]]
需求:
使用列表存储从键盘录入的3个学生,(每个学生包含:姓名,年龄)
“”"
存储3个学生信息
students = [[‘aaa’,12],[‘bbb’,18],[‘ccc’,38]]
访问第二个学生的名字
print(students[1][0])
for i in range(1,4):
print(f’请输入第{i}个学生的信息’)
name = input(‘姓名:’)
age = input(‘年龄:’)
stu = [name,age]
students.append(stu)
print(students)
遍历列表中每一个元素
for i in range(len(students)):
stu_list = students[i]
for e in stu_list:
print(e,end=’ ')
print()
“”"
深浅复制:
列表中自带的功能是浅复制
import copy
copy模块中提供了深浅复制功能
浅复制
copy.copy(x)
深复制
copy.deepcopy(x)
区别:
1.如果列表存储的数据为基本类型,深浅复制没有区别,都是复制一份新的出来
2.如果列表中存储的数据为复合对象(列表中存储的元素为列表,字典,元组…),深浅复制有区别
2.1 浅复制
尽可能复制地址
2.2 深复制
尽可能复制数据
“”"
import copy
list1 = [1,2]
list2 = [3,4]
list3 = [list1,list2]
# 调用列表的复制功能
list4 = list1.copy()
print(id(list1))
print(id(list4))
list4[0] = 100
print(list1)
print(list4)
浅复制一份list3
list5 = copy.copy(list3)
list5 = copy.deepcopy(list3)
通过索引修改值
list5[0][0] = 100
print(list3[0][0])
“”"
列表:
1.列表的切片
list[start:stop:step]
索引值为负值的时候,表示的倒数第几个数
start: 表示索引开始位置
省略不写,默认从0开始
stop:表示结束的索引位置(不包含该位置)
省略不写,默认到最后位置(包含最后一个的)
step:表示步长
不写的情况下,默认值为1
可以为负值
实现列表的反转:
list[::-1]
2.列表的增删查改
增加:
append(obj)
尾部添加元素
insert(index,obj)
在指定位置插入执行的元素
extend(list)
可以将另外一个列表中的元素,逐个添加到当前列表中
删除:
可以根据值删、可以根据索引值删
remove(obj)
pop(index)
del list[index]
clear()
查询:
查询是否包含、查询所在的位置(索引值)
obj in list
not in
count(obj)
index(obj)
得到obj在列表中所在索引值,如果列表中不包含,直接报错
修改:
list[index] = new_value
排序:
list.sort()# 从小到大
list.sort(reverse=True)# 从大到小
sorted(list)
基于源数据(不变)内容,得到一个新的列表(排序后的)
翻转:
list.reverse()
reversed(list)
基于源数据内容(不变),得到一个新的反转后的列表
3.嵌套列表的定义以及使用
列表中的元素,同样也是列表
list1 = [[[10,100],2],[3,4]]
内存:
必须能画出来
嵌套列表中元素的访问:
list[][][]
list1[0][1]
4.列表的复制操作
list.copy()
深浅复制:
import copy
copy.copy() 浅复制
copy.deepcopy() 深复制
二者区别与联系:
对于一般数据,二者同样都是实现复制一份新的出来
区别:
列表中如果存储的数据为复合对象,
浅复制:尽可能的复制引用(地址)
深复制:递归复制所有元素的内容
“”"
list1 = [1,2,3]
list2 = list1
list3 = list1.copy()
hex(地址)
print(hex(id(list1)))
print(hex(id(list2)))
print(hex(id(list3)))
list2 与 list3
“”"
2.循环录入3个学生的学生信息(姓名,年龄,性别,分数),
存储到合理的序列中(使用嵌套列表)
“”"
students = []
count = 3
for i in range(1,count + 1):
print(f’请输入第{i}个学生的信息’)
name = input(‘姓名:’)
age = eval(input(‘年龄:’))
gender = input(‘性别:’)
score = eval(input(‘分数:’))
stu = [name,age,gender,score]
students.append(stu)
print(students)
import time
start_time = time.time()
nums = []
for i in range(100000):
# nums.append(i)
nums.insert(0,i)
end_time = time.time()
print(f’耗时:{end_time-start_time}秒’)
“”"
3.生成一个包含n个(n从系统录入)英文字母(大小均可)的列表,通过对位交换的方式实现列表的反转
“”"
import random
chars = []
n = int(input(‘请输入一个正整数:’))
for i in range(n):
chars.append(chr(random.randint(65,90)))
print(chars)
print(’-----’*20)
需要交换的次数
count = n // 2
for i in range(count):
chars[i],chars[len(chars)-1-i] = chars[len(chars)-1-i],chars[i]
print(chars)
import random
l1 = [1,2,3,4,5,6,7]
l2 = [1,0,3,4,5,6,0]
for i in range(0,7):
sub_list = l2[i:i+6]
if sub_list == l1[i:i+6]:
print(‘二等奖’)
break
if len(sub_list) < 6:
break
print(sub_list)
for i in range(0,7):
sub_list = l2[i:i+4]
if sub_list == l1[i:i+4]:
print(f’四等奖,中出号码:{sub_list}’)
break
if len(sub_list) < 4:
break
“”"
list
list = []
tuple:
概念:
可以存储任意多个不同类型数据的有序集合
特点:
不可变,有序,不唯一
特性操作:
定义:
t = ()
如果存储元素,必须有’,‘
连接
+
重复
*
索引范围
[0,len(t)-1]
访问:
t[index]
存在越界问题
操作:
增加(不支持)
删除(不支持)
查询:
index()
count()
in
not in
修改(不支持)
遍历:
for in
for in range()
while i < len():
t = 1,2,3
这时候t默认为元组类型
dict
set
“”"
t = (1,)
print(type(t))
t2 = (2,)
t3 = t+t2
print(t3)
t4 = t3*2
print(t4)
print(t4[-1])
# print(t4[10]) #IndexError: tuple index out of range
t5 = ()
t5 = (1,2,3)
# del t5[0] # TypeError: ‘tuple’ object doesn’t support item deletion
print(t5)
i = t5.index(2)
print(i)
c = t5.count(2)
print©
print(1 in t5)
t5[0] = 100 # TypeError: ‘tuple’ object does not support item assignment
a, *b = 1, 2, 3
*a, b = 1, 2
print(type(a))
print(a)
print(type(b))
print(b)
print(’—’*20)
# t6 = 1, 2, 3
t6 = 1, 2, 3
print(type(t6))
print(t6)
元组的嵌套
t = ((1,2),(3,4))
t = ([1,2],[3,4])
t = [(1,2),(3,4)]
print(t[0][1])
t6 = (1,2)
基于元组的内容,创建一个新的列表
list1 = list(t6)
print(type(list1))
基于列表的内容创建元组
t7 = tuple(list1)
print(type(t7))
“”"
复合:
list
[]
tuple -> 不可变
()
---------
dict:
字典
映射关系
特点:
对于字典而言,没有索引值,没有默认顺序(无序的,Python2 完全无序, Python3.5之后添加顺序)
Python2之所以存储的数据是无序,取决于底层的数据结构
哈希表(哈希表存储数据的原理)
key唯一(值以后添加的为准)
什么类型可以做key?
一般情况下,建议使用字符串做key
不可变类型都可以做key
基本类型都为不可变类型,tuple
不可变类型 (可以做key)
bool,int,float,str,tuple
可变类型(不能做key)
list,dict,set
作用:
存数据,可以多个数据
定义:
d = {}
存储数据方式:(key:value) 键值对的存储方式
stu_dict = {‘name’:‘xxx’,‘age’:18,‘gender’:‘男’}
访问方式:
d[key]
set
“”"
# 定义一个空字典
d = {}
print(type(d))
# stu_list = [1001,‘xxx’,18,‘男’]
# print(f’姓名:{stu_list[0]} 年龄:{stu_list[1]} 性别:{stu_list[2]}’)
# 定义一个存储3个减值对元素的字典
stu_dict = {‘id’:1001,‘name’:‘xxx’,‘age’:18,‘gender’:‘男’,‘id’:1002}
print(stu_dict)
# print(f’姓名:{stu_dict[0]} 年龄:{stu_dict[1]} 性别:{stu_dict[2]}’)
# 字典中元素的访问,通过key获取对应的值
print(f’学号:{stu_dict[“id”]} 姓名:{stu_dict[“name”]} 年龄:{stu_dict[“age”]} 性别:{stu_dict[“gender”]}’)
# d1 = {65:‘A’,66:‘B’,True:1,3.5:‘PI’,[1,2]:1}
d1 = {65:‘A’,66:‘B’,True:1,3.5:‘PI’,(1,2):1}
print(d1)
# 可变类型数据无法求hash值
#v = hash([1,2,3])
a={‘e’:8,‘o’:9,‘k’:0,‘m’:22,‘b’:88}
“”"
元素的访问:
d[key]
访问的时候,如果没有指定key,则导致keyError
d.get()
访问的时候,如果没有自定key,不会报错,会得到一个None
增:
d[key] = value
setdefault()
update(key=value)
删:
pop()
popitem()随机删除
del
clear
查:
默认情况只能查key
in
not in
改:
d[key] = value
update(key=value)
country.update(IN=‘Indian’,JP=‘123’)
遍历:
keys():
获取字典中所有的key
python2 list
python3 生成器对象
values()
获取字典中所有的value
items()
获取字典中所有的键值对
“”"
country = {‘CN’:‘China’,‘JP’:‘Japan’}
print(country[‘CN’])
KeyError: ‘CH’
print(country[‘CH’])
print(country.get(‘CN’))
print(country.get(‘CH’))
# 首次出现该Key,添加
country[‘EN’] = ‘England’
后续出现该key,修改
country[‘EN’] = ‘America’
# country.setdefault(‘EN’,‘England’)
country.update(IN=‘Indian’,JP=‘123’)
print(country)
# 删除
# v = country.pop(‘IN’)
# print(v)
# # 任意删除一个
country.popitem()
print(country)
del country[‘CN’]
# country.clear()
print(country)
# 查询
print(‘China’ in country)
print(‘CN’ in country)
# 字典的遍历
for k in country:
print(f’国家简称:{k},国家全称:{country[k]}’)
for k in country.keys():
print(f’国家简称:{k},国家全称:{country[k]}’)
all_key = country.keys()
print(type(all_key))
print(all_key)
# 将dict_keys类型转换为列表类型
all_key_list = list(all_key)
print(all_key_list)
all_value = country.values()
print(all_value)
#
for value in country.values():
print(value)
print(’–’*20)
all_item = country.items()
print(all_item)
for i in country.items():
print(i)
for k,v in country.items():
# print(i)
print(k,v)
“”"
集合:Set
定义方式:
s = {}
特点:
无序,唯一
可以存储什么类型的数据?
只能存储不可变类型的数据(等同于字典的key)
集合底层数据结构:
哈希表(添加,删除,查找效率都很高)
存储原理
长度:
len(s)
注意:
集合中没有索引值
遍历:
for in
增
add(elem)
删
remove(elem)
pop()
discard(elem)
clear()
查
in
not in
改s
间接修改(删旧的,添加新的)
使用场景:
快速去重
set(list)
list()
“”"
s = {‘1’,‘a’,10,0,‘x’,1,‘1’,(1,2)}
s = {‘1’,‘a’,10,0,‘x’,1,‘1’,(1,2),[1,2]}
s = {‘1’,‘a’,10,0,‘x’,1,‘1’,(1,2),{‘a’:1,‘b’:2}}
s = set()
print(type(s))
print(s)
v = hash(‘1’)
print(v)# 1193136600182093950, 457057545219557140,7439736106587348287
print(s[0]) # TypeError: ‘set’ object does not support indexing
for i in s:
print(i)
s1 = set()
s1.add(‘a’)
s1.add(‘z’)
s1.add(‘d’)
s1.add(‘f’)
s1.add(1)
print(s1)
删除
s1.remove()
print(s1)
s1.pop()
print(s1)
s1.discard(1)
print(s1)
# list1 = [1,1,2,2,3,4,4]
# 去重列表中重复数据
# s = set(list1)
# print(s)
# 取交集,取反交集,取并集
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
# 取交集
set3 = set1 & set2
print(set3)
# 取反交集
set4 = set1 ^ set2
print(set4)
# 取并集
set5 = set1 | set2
print(set5)
“”"
字符串常用方法:
查找:
find
rfind
找不到,返回-1
----------
index
rindex
找不到,抛出异常
----------
count
统计出现次数,如果没有,得到0
拆分
split
按指定的子串,将目标字符串拆分成列表
partition
拆分成 前,中,后三个组分的元组
rpartition
转换
lower()
upper()
replace(old,new,count)
swapcase()
判断
isdigit()
判断纯数字
isalnum()
判断数字跟字母
isalpha()
纯字母
isupper()
判断大写
islower()
判断小写
推导式
列表推导式
lst = [表达式 for if for]
字典推导式
d1 = {表达式 for if for}
集合推导式
s1 = {同列表推导式}
# 唯一,无序
面试试题:
- def func(lst=[])
内部保留lst之前的值 - lst = [lambda x :x + i for i in range(10)]
lst0
“”"
s1 = ‘abc123’
print(s1.split(’ ‘))
print(s1.partition(’ '))
lst = [lambda x :x + i for i in range(10)]
print(lst0)
print(lst1)
print(lst2)
def split_custom(src,sub):# 晚自习继续
lst = []
start = 0
end = 0
for i in range(len(src)):
if sub == src[i:i+len(sub)]:
end = i
lst.append(src[start:end])
print(src[start:end])
start = end+len(sub)
lst.append(src[start:])
return lst
print(split_custom(‘a,b,cd,’,’,c’))
“”"
基础练习题
1.封装自定义函数,功能类似lower(src)
2.封装自定义函数,功能类似upper(src)
3.封装函数,功能类似find(src,sub)
4.封装函数,功能类似rfind(src,sub)
5.封装函数,功能类似isdigit(src)
6.封装函数,功能类似partition(src,sub)
7.封装函数,功能类似split(src,sub)
能力提升
1.封装函数,功能类似startswith(src,sub)判断字符串src是否以字符串sub的内容开头
2.封装函数,功能类似endswith(src,sub)判断字符串src是否以字符串sub的内容结尾
“”"
#1.封装自定义函数,功能类似lower(src)
def lower_custom(src):
s = ‘’
for ch in src:
if ‘A’ <= ch <= ‘Z’:
# 转小写
ch = chr(ord(ch)+32)
s += ch
return s
print(lower_custom(‘aBC123D’))
2.封装自定义函数,功能类似upper(src)
def upper_custom(src):
s = ‘’
for ch in src:
if ‘a’ <= ch <= ‘z’:
# 转大写
ch = chr(ord(ch) - 32)
s += ch
return s
print(upper_custom(‘aBC123D’))
3.封装函数,功能类似find(src,sub)
def find_custom(src,sub):
for i in range(len(src)):
if src[i:i+len(sub)] == sub:
return i
return -1
print(find_custom(‘abcd123’,‘d1’))
print(find_custom(‘abcd123’,‘1d’))
4.封装函数,功能类似rfind(src,sub)
def rfind_custom(src,sub):
for i in range(len(src)-1,-1,-1):
if src[i:i+len(sub)] == sub:
return i
return -1
rfind_custom(‘abc123c10’,‘c1’)
“”"
5.封装函数,功能类似isdigit(src)
6.封装函数,功能类似partition(src,sub)
7.封装函数,功能类似split(src,sub)
能力提升
1.封装函数,功能类似startswith(src,sub)判断字符串src是否以字符串sub的内容开头
2.封装函数,功能类似endswith(src,sub)判断字符串src是否以字符串sub的内容结尾
“”"
5.封装函数,功能类似isdigit(src)
def isdigit_custom(src):
for ch in src:
if not ‘0’ <= ch <= ‘9’:
return False
return True
print(isdigit_custom(‘123a’))
print(isdigit_custom(‘123’))
6.封装函数,功能类似partition(src,sub)
import demo02_作业讲解1
def partition_custom(src, sub): # abc123 c1 -> 2 src[:2]
if sub in src:
# 1 查找索引值
i = demo02_作业讲解1.find_custom(src, sub)
# 2 根据索引值切片操作
# 3 返回元组
return (src[:i], sub, src[i + len(sub):])
else:
return (src, ‘’, ‘’)
print(partition_custom(‘abc123c145’,‘c1’))
print(partition_custom(‘abc123’,‘c3’))
7.封装函数,功能类似split(src,sub)
def split_custom(src, sub): # 晚自习继续
pass
1.封装函数,功能类似startswith(src,sub)判断字符串src是否以字符串sub的内容开头
def startswith_custom(src, sub, start=None, stop=None):
if start == None and stop == None:
return sub == src[0:len(sub)]
else:
src = src[start:stop]
return sub == src[0:len(sub)]
print(startswith_custom(‘abc123’,‘abc1’))
print(startswith_custom(‘abc123’,‘babc1’))
print(startswith_custom(‘abc123’,‘abc1’,1,5))
2.封装函数,功能类似endswith(src,sub)判断字符串src是否以字符串sub的内容结尾
def endswith_custom(src, sub):
# return sub == src[len(src)-len(sub):]
return sub == src[-len(sub):]
print(endswith_custom(‘abc123’, ‘123’))
print(endswith_custom(‘abc123’, ‘1234’))
“”"
-
什么是模块?
一个.py文件就被称为一个模块
2.模块的分类
2.1 内置模块
2.2 系统标准模块
random
time
sys
2.3 第三方模块
pygame2.4 自定义模块
-
模块中的内容(可以写任意内容)
变量
函数
可执行的代码
4.封装一个自定义模块(求圆的面积,求圆的周长)
5.模块的使用
5.1 引入模块
import 模块1,模块2
import 模块名 as 新名字
import 模块1名 as 新名字1,模块2名 as 新名字2
引入之后,功能的使用
模块名/新名.变量/函数
import random
random.randint(a,b)
注意:
1.import 模块时, 模块中的内容会被加载到系统内存(会执行一遍)
2.无论被引入多少次,只加载一次
5.2 引入模块中的部分功能
from 模块 import 功能(变量,函数)
from 模块 import 功能(变量,函数) as 新功能名
from 模块 import 功能1,功能2,功能3(变量,函数)
from 模块 import *
默认引入所有,如果有__all__ = [],只引入列表中包含的
使用方式:
直接使用,不用带模块名
功能()
注意:
只有手动引入的,可以使用,其他的无法使用
“”"
import circle
r = eval(input(‘输入圆的半径:’))
s = circle.get_area®
print(f’半径为:{r}的圆的面积为:{s}’)
import circle as c
import circle as c
import circle as c
r = eval(input(‘输入圆的半径:’))
s = c.get_area®
print(f’半径为:{r}的圆的面积为:{s}’)
from circle import PI,get_area as ga
print(PI)
# s = get_area(2)
s = ga(2)
print(s)
*
from circle import *
print(PI)
s = get_area(2)
# l = get_perimeter(2)
“”"
包: package
python2
文件夹(必须包含一个名称为__init__.py的模块)
python3
文件夹
包的用途:
1.整理作用
2.不同的包中,可以存在同名模块
存储在包中的模块如何引用:
import 包名.模块名
使用
包名.模块名.功能
from 包名.模块名... import 变量名
from 包名.模块名... import 变量名 1,变量名 2...
from 包名 import 模块名
from 包名 import 模块名,模块名 1...
“”"
import package1.circle
print(package1.circle.PI)
import package1.circle as a
print(a.PI)
from package2.module1 import PI
print(PI)
从包中引入模块
from package1 import circle
print(circle.PI)
“”"
面向对象:
封装
继承
多态
面向过程与面向对象
面向过程:
1.
2.
3.
面向对象:
对象
如何把大象装进冰箱里:
面向过程:
1.打开冰箱门
2.将大象装进去
3.关上冰箱门
面向对象:
找个人(对象)
开车:
面向过程的思想:
1.系安全带
2.踩离合
3.打火
4.松手刹
5.挂挡
6.松离合/给油
面向对象:
找个司机(对象)
吃个蛋炒饭
面向过程:
1.先蒸米饭
2.炒鸡蛋
3.炒米
4.出锅
面向对象:
找个饭馆(厨师)
“”"
“”"
面向对象:
类(抽象的,整体,模板)
对象(具体的东西,人,个体,具体的实物)
先有类,基于类可以创建出任意多个的对象
类中存储共性的东西
所有对象都是基于类的模板创建出来的
奥迪汽车 类
张三停在车库的奥迪A8 对象
雅迪 类
人 类
咱班坐在xx的xx 对象
笔记本 类
thinkPad 类
小明的thinkPad 对象
“”"
"""
面向对象:
类(抽象的,整体,模板)
对象(具体的东西,人,个体,具体的实物)
先有类,基于类可以创建出任意多个的对象
类中存储共性的东西
所有对象都是基于类的模板创建出来的
奥迪汽车 类
张三停在车库的奥迪A8 对象
雅迪 类
人 类
咱班坐在xx的xx 对象
笔记本 类
thinkPad 类
小明的thinkPad 对象
"""
"""
自定义一个类
class 类名:
pass
驾驶员类:
属性:
行为:
函数/方法
开车
创建对象的语法:
变量(对象)名 = 类名()
调用方法语法:
对象名.方法名(实参)
"""
# 自定义类
class Driver:
# 行为: 自定义一个方法
def drive_car(self):
print('1.踩离合')
print('2.打火')
print('3.挂挡')
print('4.松离合/给油')
print('嘀嘀嘀,走起~~~')
# 创建一个对象
d = Driver()
# 通过对象,调用对象的功能
d.drive_car()
# 创建一个字符串对象
s = 'abc123'
i = s.find('c1')
# l = [1,2,0,-3]
# l.sort()
"""
面向对象:
面向过程
注重步骤与算法
面向对象
对象
类与对象
类(模板,先封装类)
对象(基于模板创建的实例)
类的分类:
系统类
自定义类
类的组成:
属性:
行为:
创建类的语法:
class 类名(object):
经典类(旧式类)
class 类名:
pass
新式类:
class 类名(object):
pass
基于类创建对象:
对象名 = 类名()
调用对象方法:
对象名.方法名(参数...)
"""
# 封装一个学生类
class Student:
def study(self):
print('我爱学习,一天不写代码,难受~~~')
def eat(self):
print('我爱吃,一天不吃,难受~~~~')
# 创建对象
stu1 = Student()
# 调用方法
stu1.study()
"""
面向对象特征:
1.封装
类的封装
属性(成员变量)
动态添加属性:
对象名.属性名 = value
访问属性:
对象名.属性名
为类模板添加属性:
__init__(self)方法
创建对象时会被调用
每创建一个对象都会被调用一次
行为(成员函数<方法>)
2.继承
3.多态
"""
class Student:
def __init__(self,name_,age_):
print('我是初始化方法,现在被调用了')
self.name = name_
self.age = age_
# 打印self的地址
print(id(self))
def study(self):
print('我爱学习,一天不写代码,难受~~~')
# 创建对象
stu1 = Student('小强',18)
print(id(stu1))
# 动态为对象添加属性
# stu1.name = '小明'
# stu1.age = 18
# # 打印对应的键值对属性
print(stu1.__dict__)
print(dir(stu1))
# # print(dir(Student))
# print(stu1.name)
# print(stu1.age)
# # 调用方法
# stu1.study()
print('------------------')
stu2 = Student('铁锤',20)
print(id(stu2))
print(dir(stu2))
print(stu2.__dict__)
# print(stu2.name)
"""
面向对象:
1.把类封装好
2.处理类与类之间的关系
属性/方法的访问方式:
对象.属性/方法
self 关键字的用法:
作为方法的第一形参:
表示的当前类的一个对象,哪个对象调用,这个self表示的就是谁
访问当前类的属性:
访问当前类的方法:
"""
class Student(object):
def __init__(self,name,age):
self.name = name
self.age = age
def sleep(self):
self.play_game()
print('闭上眼睛,躺床上睡')
def play_game(self):
print('玩把游戏')
# self.sleep()
def introduce(self):
print(f'introduce:{id(self)}')
print(f'我叫{self.name},今年{self.age}岁')
stu1 = Student('小明',18)
#
# print(id(stu1))
# stu1.introduce()
# stu2 = None
# stu2.introduce()
stu3 = Student('小青',18)
stu3.introduce()
stu3.sleep()
"""
1.类的封装
属性
行为
2.类的交互
方法(参数)
需求:
光明英雄
属性:
名字
生命值
攻击力
行为
攻击(黑暗)
普通攻击(黑暗)
技能攻击(黑暗)
黑暗英雄
属性:
名字
生命值
攻击力
行为
攻击(光明)
普通攻击(光明)
技能攻击(光明)
创建两个英雄
while True:
互相伤害
判断输赢以及结束问题
"""
import random
import time
class Hero_Dark:
def __init__(self,name,hp,damage):
self.name = name
self.hp = hp
self.damage = damage
def attack(self,light_hero):
n = random.randint(1,1)
if n == 1:
self.attack_common(light_hero)
# 普通伤害
def attack_common(self,light_hero):
real_damage = self.damage + random.randint(5,20)
light_hero.hp -= real_damage
print(f'{self.name}普通攻击{light_hero.name},{light_hero.name}损失生命值{real_damage},剩余生命值{light_hero.hp}')
# 技能伤害
# def attack_skill(self, light_hero):
# pass
class Hero_Light:
def __init__(self, name, hp, damage):
self.name = name
self.hp = hp
self.damage = damage
def attack(self, dark_hero):
n = random.randint(1,1)
if n == 1:
self.attack_common(dark_hero)
def attack_common(self, dark_hero):
real_damage = random.randint(1,25)+self.damage
dark_hero.hp -= real_damage
print(f'{self.name}普通攻击{dark_hero.name},{dark_hero.name}损失生命值{real_damage},剩余生命值{dark_hero.hp}')
# 创建对象
hero_dark = Hero_Dark('小怪兽',10000,20)
hero_light = Hero_Light('奥特曼',8000,25)
# 持续性的互相伤害
count = 1
while True:
print(f'第{count}回合')
hero_light.attack(hero_dark)
if hero_dark.hp <= 0:
print(f'{hero_dark.name}输了')
break
hero_dark.attack(hero_light)
if hero_light.hp <= 0:
print(f'{hero_light.name}输了')
break
time.sleep(0.005)
count += 1
"""
1.类的封装
属性
行为
2.类的交互
方法(参数)
需求:
光明英雄
属性:
名字
生命值
攻击力
行为
攻击(黑暗)
普通攻击(黑暗)
技能攻击(黑暗)
黑暗英雄
属性:
名字
生命值
攻击力
行为
攻击(光明)
普通攻击(光明)
技能攻击(光明)
创建两个英雄
while True:
互相伤害
判断输赢以及结束问题
"""
import random
import time
# 技能类
class Skill:
def __init__(self,sk_name,sk_damage):
# 技能名
self.skill_name = sk_name
# 技能伤害值
self.skill_damage = sk_damage
class Hero_Dark:
def __init__(self,name,hp,damage,q,r):
self.name = name
self.hp = hp
self.damage = damage
self.skillQ = q
self.skillR = r
def attack(self,light_hero):
n = random.randint(1,2)
if n == 1:
self.attack_common(light_hero)
else:
self.attack_skill(light_hero)
# 普通伤害
def attack_common(self,light_hero):
real_damage = self.damage + random.randint(5,20)
light_hero.hp -= real_damage
print(f'{self.name}普通攻击{light_hero.name},{light_hero.name}损失生命值{real_damage},剩余生命值{light_hero.hp}')
# 技能伤害
def attack_skill(self, light_hero):
n = random.randint(1,2)
if n == 1:
light_hero.hp -= self.skillQ.skill_damage
print(f'{self.name}释放技能\033[1;34m{self.skillQ.skill_name}\033[0m,{light_hero.name}损失生命值{self.skillQ.skill_damage},剩余生命值{light_hero.hp}')
else:
light_hero.hp -= self.skillR.skill_damage
print(
f'{self.name}释放技能{self.skillR.skill_name},{light_hero.name}损失生命值{self.skillR.skill_damage},剩余生命值{light_hero.hp}')
class Hero_Light:
def __init__(self, name, hp, damage):
self.name = name
self.hp = hp
self.damage = damage
def attack(self, dark_hero):
n = random.randint(1,1)
if n == 1:
self.attack_common(dark_hero)
# 普通伤害
def attack_common(self, dark_hero):
real_damage = random.randint(1,25)+self.damage
dark_hero.hp -= real_damage
print(f'{self.name}普通攻击{dark_hero.name},{dark_hero.name}损失生命值{real_damage},剩余生命值{dark_hero.hp}')
# 技能伤害
def attack_skill(self,dark_hero):
pass
sk_Q = Skill('偷天换日',99)
sk_R = Skill('偷梁换柱',120)
# 创建对象
hero_dark = Hero_Dark('小怪兽',1000,20,sk_Q,sk_R)
hero_light = Hero_Light('奥特曼',850,25)
# 持续性的互相伤害
count = 1
# print("\033[1;32m 字体颜色:深黄色\033[0m")
while True:
print(f'第{count}回合')
hero_light.attack(hero_dark)
if hero_dark.hp <= 0:
print(f'{hero_dark.name}输了')
break
hero_dark.attack(hero_light)
if hero_light.hp <= 0:
print(f'{hero_light.name}输了')
break
time.sleep(0.25)
count += 1
"""
私有化:
私有属性:
语法:
self.__属性名 = value
私有属性,不可以在类外访问(获取值)
直接在类外,为私有属性设置值(无效)
注意:
对于私有属性,一般情况会提供对应的读写方法(setXXX() getXXX())
不是真正上的私有化,而是名字重整(改名)
私有方法:
def __方法名(参数):
pass
私有方法只能类内使用,不能类外访问
符合名字重整的原则:
_类名__私有方法/属性名
"""
class Student:
def __init__(self,name,age):
self.name = name
# self.age = age
# 私有属性
# self.__age = age
self.setAge(age)
def setAge(self,age):
if 0 < age <= 120:
self.__age = age
else:
print('年龄有误,默认设置1')
self.__age = 1
def getAge(self):
return self.__age
def introduce(self):
print(f'我叫{self.name},今年{self.__age}岁')
self.__func1()
# 类内定义的私有方法
def __func1(self):
print(f'我是私有方法:__func1')
stu1 = Student('鼠标',2300)
# stu1.__age = -3
# 不能在类外直接访问私有属性
# print(f'年龄:{stu1.__age}')
# 通过修改年龄的方法,修改年龄值
stu1.setAge(19)
print(stu1.getAge())
# 通过重整之后的名字访问私有属性(不提倡)
# stu1._Student__age = 1000
# stu1.introduce()
print(dir(stu1))
# 无法通过对象访问私有方法
# stu1.__func1()
# 访问名字重整后的方法(不提倡)
stu1._Student__func1()
"""
面向对象:
1.封装
2.继承
查阅资料(了解类与类之间的关系)
父类(超类,根类,基类)
子类(孩子类,派生类)
继承的语法:
class 类名(父类):
pass
继承的作用:
子类可以访问父类中所有的非私有的属性,方法
继承的好处:
减少重复代码(减少代码冗余度)
易拓展,易维护
如果一个类,没有明确指明父类是谁,则默认父类是object
class 类名(object):
pass
3.多态
"""
class Dog:
def __init__(self,name,color,age):
self.name = name
self.color = color
self.age = age
def shout(self):
print('会叫~~~~')
def lookafter_home(self):
print('看家')
class Cat:
def __init__(self, name, color, age):
self.name = name
self.color = color
self.age = age
def shout(self):
print('会叫~~~~')
def catch_mouse(self):
print('猫抓耗子')
class Pig:
def __init__(self, name, color, age):
self.name = name
self.color = color
self.age = age
def shout(self):
print('会叫~~~~')
dog1 = Dog('大黄','yellow',3)
cat1 = Cat('小黑','black',2)
dog1.shout()
dog1.lookafter_home()
cat1.shout()
cat1.catch_mouse()
"""
面向对象:
1.封装
2.继承
查阅资料(了解类与类之间的关系)
父类(超类,根类,基类)
子类(孩子类,派生类)
继承的语法:
class 类名(父类):
pass
继承的作用:
class 类名(object):
pass
3.多态
"""
class Animal:
def __init__(self, name, color, age):
self.name = name
self.color = color
self.age = age
def shout(self):
print('会叫~~~~')
def __sleep(self):
print('私有方法睡觉')
class Dog(Animal):
def lookafter_home(self):
print('看家')
class Cat(Animal):
def catch_mouse(self):
print('猫抓耗子')
class Pig(Animal):
pass
dog1 = Dog('大黄','yellow',3)
cat1 = Cat('小黑','black',2)
dog1.shout()
print(dog1.name)
dog1.lookafter_home()
cat1.shout()
cat1.catch_mouse()
# cat1.__sleep()
# 查看Cat的父类
print(Cat.__bases__)
print(Animal.__bases__)
"""
__init__(self)
调用时机:
创建对象会被调用,每创建一个对象,都会被调用一次
作用:
为类模板添加属性
做对象初始化的处理
self关键字的意义:
self表示的当前类的一个对象
谁调用的时候,表示的就是谁
可以访问当前类的属性以及方法
封装中私有化问题:
语法:
私有属性:
self.__属性名()
提供读写方法:
读:
def get属性():
写:
def set属性(self,形参)
self.属性 = 形参
私有方法:
def __方法名()
私有化后的影响:
私有化的属性/方法,只能类内访问
不能类外访问
python中的私有化,不是真正的私有化:本质是名字重整
重整规则:
属性: _类名__私有属性名
方法: _类名__私有方法名
继承:
语法:
class 子类(父类):
pass
class 子类: #不指明父类,则默认父类为object
pass
作用:
子类可以继承父类中所有非私有的属性,跟方法
好处:
精简代码
易维护,易拓展
"""
"""
1.封装狙击手类
属性:
名字
枪 = None
行为:
捡枪(枪)
装弹<创建弹夹,循环创建子弹,装进弹夹里,然后把弹夹装到枪上>
瞄准(敌人)
射击(敌人)<调用枪的射击方法>
2.封装枪类
属性:
型号
弹夹=None
行为:
射击(敌人)<打出一颗子弹>
"""
import time
class Sniper:
def __init__(self,name):
self.name = name
self.gun = None
# 捡枪, 参数gun就是要捡起来的枪
def pickup_gun(self,gun):
self.gun = gun
print(f'狙击手【{self.name}】捡起一把【{gun.type}】')
# 装弹
def load(self):
# 创建一个弹夹对象
clip = Clip(10)
# 循环装子弹
print('装弹中')
for i in range(clip.capacity):
time.sleep(0.2)
print(f'第{i+1}发')
bullet = Bullet()
clip.bullet_list.append(bullet)
print('装弹完成')
# 将弹夹装到枪上
self.gun.clip = clip
class Gun:
def __init__(self,type):
self.type = type
# 弹夹属性值为None
self.clip = None
# 弹夹类
class Clip:
def __init__(self,capacity):
# 弹夹容量
self.capacity = capacity
# 存储子弹对象的容器
self.bullet_list = []
# 子弹类
class Bullet:
def __init__(self):
# 子弹伤害值
self.damage = 100
self.speed = 100
def move(self):
print('让子弹飞一会~~~')
# 创建选手
sniper = Sniper('001')
# 创建枪
gun = Gun('AWM')
# 选手捡枪
sniper.pickup_gun(gun)
# 装弹
sniper.load()
"""
1.封装狙击手类
属性:
名字
枪 = None
行为:
捡枪(枪)
装弹<创建弹夹,循环创建子弹,装进弹夹里,然后把弹夹装到枪上>
瞄准(敌人)
射击(敌人)<调用枪的射击方法>
2.封装枪类
属性:
型号
弹夹=None
行为:
射击(敌人)<打出一颗子弹>
3.封装弹夹类
属性:
弹夹容量
存储子弹的列表
4.封装子弹类
属性:
伤害值
行为:
移动
"""
import time
class Sniper:
def __init__(self,name):
self.name = name
self.gun = None
# 捡枪, 参数gun就是要捡起来的枪
def pickup_gun(self,gun):
self.gun = gun
print(f'狙击手【{self.name}】捡起一把【{gun.type}】')
# 装弹
def load(self):
# 创建一个弹夹对象
clip = Clip(10)
# 循环装子弹
print('装弹中')
for i in range(clip.capacity):
time.sleep(0.2)
print(f'第{i+1}发')
bullet = Bullet()
clip.bullet_list.append(bullet)
print('装弹完成')
# 将弹夹装到枪上
self.gun.clip = clip
# 瞄准
def aim_at(self,enemy):
print(f'瞄准敌人{enemy.name}')
# 调用射击
self.shoot(enemy)
# 射击
def shoot(self,enemy):
print('扣动扳机,砰~~~')
# 调用枪的射击,得到一颗子弹
bullet = self.gun.shoot(enemy)
# 子弹飞向敌人
bullet.move(enemy)
class Gun:
def __init__(self,type):
self.type = type
# 弹夹属性值为None
self.clip = None
# 射击
def shoot(self,enemy):
# 弹夹中的子弹数量-1
b = self.clip.bullet_list.pop()
print(f'打出一颗子弹,剩余子弹{len(self.clip.bullet_list)}发')
return b
# 弹夹类
class Clip:
def __init__(self,capacity):
# 弹夹容量
self.capacity = capacity
# 存储子弹对象的容器
self.bullet_list = []
# 子弹类
class Bullet:
def __init__(self):
# 子弹伤害值
self.damage = 100
self.speed = 100
def move(self,enemy):
print(f'子弹飞向敌人{enemy.name}')
# 敌人中弹
enemy.get_shot(self)
# 敌人类
class Enemy:
def __init__(self,name):
self.name = name
self.hp = 100
# 被打中之后的行为
def get_shot(self,bullet):
self.hp -= bullet.damage
print(f'【{self.name}】中弹,剩余生命值:【{self.hp}】')
# 创建选手
sniper = Sniper('001')
# 创建枪
gun = Gun('AWM')
# 选手捡枪
sniper.pickup_gun(gun)
# 装弹
sniper.load()
# 创建一个敌人
enemy = Enemy('伏地魔')
# 调用选手的瞄准方法
sniper.aim_at(enemy)
"""
多继承条件下的super的意义:
super 表示直接找父类,而是取决于__mro__的顺序
python3 广度优先的搜索算法
python2下:
如果是旧式类(经典类):
深度优先
如果是新式类
广度优先
"""
class A:
def func(self):
print('A.func')
class B(A):
def func(self):
print('B.func')
super(B, self).func()
class C(A):
def func(self):
print('C.func')
super(C, self).func()
class D(B,C):
def func(self):
print('D.func')
# super(D, self).func()
# super(self.__class__).func()
d = D()
d.func()
print(D.__mro__)# d->b->c->a
#运行结果
# D.func
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
"""
封装
继承
多态:
继承是前提,没有继承就没有多态
方法重写
多态:指的是方法的多态
同一个方法名,由于调用对象的不同,可能会有不同的执行效果
不同国家的人吃饭
"""
class Human:
def eat(self):
print('人都需要吃饭')
class Chinese(Human):
def eat(self):
print('中国人使用筷子吃饭')
class Indian(Human):
def eat(self):
print('三个使用手抓饭')
class English(Human):
def eat(self):
print('英国人使用刀叉吃饭')
# p = Human()
p = Chinese()
p.eat()
"""
# 抽象类:
# 什么是抽象类?
# 包含抽象方法的类,就是抽象类
#
# 抽象方法?
# class Animal(metaclass=ABCMeta)
# @abstractmethod
#
# 抽象类与普通类的区别?
# 是否包含抽象方法
#
# 抽象类的特性:
# 不能实例化(不能创建对象)
#
# 作用:
# 可以规范子类的行为(要求子类必须重写父类中的抽象方法,如果不重写,子类依旧是抽象类)
#
# 什么场景下使用抽象类?
# 对于不适合创建对象的类
#
# """
# from abc import abstractmethod,ABCMeta
# class Animal(metaclass=ABCMeta):
# a = 10
# @abstractmethod
# def shout(self):
# print('动物会叫')
# # @abstractmethod
# def eat(self):
# print('动物都需要吃东西')
#
# #TypeError: Can't instantiate abstract class Animal with abstract methods shout
# # a = Animal()
#
# class Dog(Animal):
# def shout(self):
# print('汪汪汪~~~')
# dog1 = Dog()
# dog1.shout()
# dog1.eat()
# print(dog1.a)
"""
魔法方法(magic method):
不用手动调用,在一定场景下,会被自动触发的方法,称为魔法
特点:
__方法名__()
注意:
自定义方法避免使用这种方式
__str__()
"""
class Dog:
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return f'name:{self.name} age:{self.age}'
dog1 = Dog('大黄',3)
print(dog1)
# python 会默认执行 dog1.__str__()
print(dog1.__str__())
"""
__call__
一个对象被当成方法调用时,会自动执行
__repr__
用法类似__str__,是__str__的备胎
"""
class A:
def __init__(self,v1,v2):
self.v1 = v1
self.v2 = v2
def __call__(self, *args, **kwargs):
print('__call__被调用')
print(args,kwargs)
def __repr__(self):
return f'repr :v1 = {self.v1}, v2 = {self.v2}'
def __str__(self):
return f'str: v1 = {self.v1}, v2 = {self.v2}'
# a = A()
# a(1,2,3)
a = A(1,2)
# print(a)
print('%r'%a)
print('%s'%a)
"""
__new__:
创建对象时,分配内存的时候会被自动触发
__del__
当对象要被系统回收时,会被触发
"""
class A:
def __new__(cls, *args, **kwargs):
print('__new__')
return super().__new__(cls)
def __init__(self,name):
print('__init__')
self.name = name
def __del__(self):
print('__del__')
print(f'{self.name}要被系统收走了')
def func1():
a0 = A('葫芦爷爷')
func1()
a1 = A('大娃')
a2 = A('二娃')
a3 = A('三娃')
a4 = A('四娃')
while True:
pass