0406线性回归

线性回归就是根据已有的x1,x2,y数据,求出x1,x2前系数k1,k2的大致数值
y=k1x1+k2x2,可先转化成矩阵的形式并且通常会有个误差项。机器学习:机器学习已有数据,计算出最待合目标方程的参数。

0409

热水器耦合器和开水断电保修

已经向PDD联系,表示会补发耦合器

Python PASS语句

pss语句,什么都不做,只是一个占位符,用到需要写语句的地方

1
2
3
4
5
6
answer=input('您是会员吗?y/n')
#判断是否是会员
if answer==’y’:
pass
else:
pass

Python条件不需要加括号,内部语句使用2个空格也就是TAB

0411

列表lst[]中的值序号从左到右从0到n-1,从右到左是-1到-N

1
2
3
4
lst=['he11o','world',98]
print (lst)
print(lst[2])
print (lst[-3])

in和not in用于判断在列表中是否存在返回值true,false

1
2
3
4
5
lst=[10,20,’python',’he11o']
print (10 in lst) #True
print (100 in lst) #False
print (10 not in lst) #False
print(100 not in lst) #True

append用于向列表的末尾添加一个元素,列表ID不变也就是不是新列表而是原列表

1
2
3
4
lst=[10,20,30]
print('添加元素之前',lst,id(lst))
lst.append (100)
print('添加元素之后',lst,id(lst))

lst.extend用于直接添加元素不保留数组格式,而append会保留

1
2
3
4
5
6
7
8
9
lst=[10,20,30]
print('添加元素之前',lst,id(lst))
lst.append (100)
print('添加元素之后',lst,id(lst))
lst2=['hello','ok']
lst.append (lst2)
print('添加元素之后1',lst,id(lst))
lst.extend(lst2)
print('添加元素之后2',lst,id(lst))

结果如下:

1
2
3
4
添加元素之前 [10, 20, 30] 2616022525760
添加元素之后 [10, 20, 30, 100] 2616022525760
添加元素之后1 [10, 20, 30, 100, ['hello', 'ok']] 2616022525760
添加元素之后2 [10, 20, 30, 100, ['hello', 'ok'], 'hello', 'ok'] 2616022525760

lst.insert#在任意位置上添加一个元素,第一个参数是位置

1
2
3
#在任意位置上添加一个元素
lst.insert(1,90)
print (lst)

lst切片操作,第一个参数是位置序号,从该位置开始替换为lst3数组

1
2
3
4
5
lst=['he11o','world',98]
lst3=['True','False','hello']
#在任意的位置上添加多个元素
lst[1:]=lst3
print(lst)

lst.remove从列表中移除一个元素,如果有重复元素只移第一个元素

1
2
3
4
lst=[10,20,30,40,50,60,30]
lst.remove(30) #从列表中移除一个元素,如果有重复元素只移第一个元素
print(lst)
lst.remove(100#从列表中移除元素的序号超过阈值报错

0412

lst.pop()根据索引移除元素,pop中为所要移除的索引序号

1
2
3
lst=[10,20,30,40,50,60,30]
lst.pop (1)
print (lst)

结果为[10, 30, 40, 50, 60, 30]

1
2
3
4
5
6
lst=[10,20,30,40]
#一次修改一个值
lst[2]=100
print (lst)
lst[1:3]=[300,400,500,600]
print (lst)

结果为:
[10, 20, 100, 40]
[10, 300, 400, 500, 600, 40]
lst.sort用于直接排序,默认升序

1
2
3
4
5
6
7
8
lst=[10,20,30,40,50,60,90]
print('排序后的列表',lst,id(lst))
#通过指定关键字参数,将列表中的元素进行降序排序
lst.sort (reverse=True)
#reverse=Irue表示降序排序,reverse=False就是升序排序
print (lst)
lst.sort (reverse=False)
print(lst)

结果为
[90, 60, 50, 40, 30, 20, 10]
[10, 20, 30, 40, 50, 60, 90]
sorted函数排序会产生新的列表对象lst

1
2
3
4
5
6
7
8
#开始排序
lst=[10,20,30,40]
new_list=sorted (lst)
print (lst)
print (new_list)
#指定关键字参数,实现列表元素的降序排序
desc_list=sorted(lst,reverse=True)
print (desc_list)

[ii for i in range(1,10)]
i
i表示列表元素的表达式,i表示自定义变量,range(1,10)表示可迭代对象
结果为[1, 4, 9, 16, 25, 36, 49, 64, 81]

0417

字典Python内置的数据结构之一,与列表一样是一个可变序列【支持增删改查】
以键值对的方式存储数据,字典是一个无序的序列,第一个放进来的不一定在第一个位置上即为无序,因为位置是经过hash函数计算得来的
字典的创建 最常用的方式:使用花括号

1
2
3
scores={'张三':100,'李四':98,'王五':45}
print (scores)
print (type (scores))

dict()创建

1
2
student=dict (name='jack',age=20)
print (student)

[]取值或者get()取值,get()取值会好一点不会报错!

1
2
3
4
scores={'张三':100,'李四':98,'王五':45}
print(scores['张三'])
print(scores.get('张三'))
print(scores.get('陈六'))

in和not in判断是否存在元素以下为删改查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
scores={'张三':100,'李四':98,'王五':45}
print('张三' in scores)
print('张三' not in scores)
del scores['张三']
#删除指定的key-value对
scores.clear()
#清空字典的元素
print (scores)
scores['陈六']=98
#新增元素
print (scores)
scores['陈六']=100
#修改元素
print (scores)

运行结果

1
2
3
4
5
6
7
True
False
{}
{'陈六': 98}
{'陈六': 100}

进程已结束,退出代码0

字典中有键key,值value,元组key-value三部分组成例如{'张三':100,'李四':98,'王五':45}中,'张三'为键key,100为值value,合起来叫元组。
获取值

1
2
3
4
5
6
7
8
{'陈六': 100}
#获取所有的value
values=scores.values()
print (values)
print (type(values))
print(list (values))
#获取所有的key-value对
scores.items()

结果:

1
2
3
dict_values([100])
<class 'dict_values'>
[100]

获取Key

1
2
3
4
5
6
#获取所有的key
keys=scores.keys()
print (keys)
print (type (keys))
print (list (keys))
#将所有的key组成的视图转成列表

获取key-value

1
2
3
4
5
6
scores={'张三':100,'李四':98,'王五':45}
#获取所有的key-value对
items=scores.items ()
print (items)
print (list (items))
#转换之后的列表元素是由元组组成

结果:

1
2
dict_items([('张三', 100), ('李四', 98), ('王五', 45)])
[('张三', 100), ('李四', 98), ('王五', 45)]

字典元素的遍历,获取字典元素的键

1
2
3
4
scores={'张三':100,'李四':98,'王五':45}
for i in scores:
print(i)
print (i,scores[i],scores.get (i))

结果:

1
2
3
4
5
6
7
张三
张三 100 100
李四
李四 98 98
王五
王五 45 45
进程已结束,退出代码0

·字典的特点
字典中的所有元素都是一个key-value对,key不允许重复,value可以
重复
·字典中的元素是无序的
·字典中的key必须是不可变对象
字典也可以根据需要动态地伸缩
·字典会浪费较大的内存,是一种使用空间换时间的数据结构
两列表一个做键,另一个做值最后合并

1
2
3
4
items=['Fruits','Books','Others']
prices=[96,78,85]
d={item:price for item,price in zip(items,prices)}
print (d)

{'Fruits': 96, 'Books': 78, 'Others': 85}
·元组
·Python内置的数据结构之一,是一个不可变序列
不可变序列与可变序列
不变可变序:字符串、元组
·不变可变序列:没有增、删,改的操作,或者操作后地址更改
·可变序列列表、字典
·可变序列:可以对序列执行增、删、改操作,对象地址不发生更改

1
2
3
4
5
6
t=('Python',world',98)
print (t)
print (type (t))
t2='Python’,’world',98#省略了小括号
print (t2)
print (type (t2))

元组数据用()表示也可以用tuple #如果元组中只有一个元素,逗号不能省
以下为元组t

1
2
3
4
5
6
t=(10,[20,30],9)
print (t)
print (type (t))
print (t[0],type (t[0]),id(t[0]))
print(t[1],type(t[1]),id(t[1]))
print (t[2],type (t[2]),id (t[2]))
1
2
3
4
5
(10, [20, 30], 9)
<class 'tuple'>
10 <class 'int'> 2269279683088
[20, 30] <class 'list'> 2269281052480
9 <class 'int'> 2269279683056

尝试将t[1]修改为100若直接t[1]=100会报错因为元组是不允许修改元素的
又由于[20,30]列表,而列表是可变序列,所以可以向列中添加元素,而列表的内存地址不变
t[1].append(100)#向列表中添加元素print (t,id(t[1]))结果为(10, [20, 30, 100], 9) 2420456023872
元组是可迭代对象,所以可以使用for.in进行遍历

1
2
3
t=(10,[20,30],9)
for item in t:
print (item)

结果为

1
2
3
10
[20, 30]
9

集合

·集合Python语言提供的内置数据结构
·与列表、字典一样都属于可变类型的序列,集合是没有value的字典
集合的创建方式直接()例如s={'Python','hello'90}
·使用内置函数set()
集合会自动去重复

1
2
s={2,3,4,5,5,6,7,7}
print (s)

结果为{2, 3, 4, 5, 6, 7}
集合间的关系
两个集合是否相等
可以使用运算符==或!=进行判断
个集合是否是另一个集合的子集
可以调用方法issubset进行判断如print(s2.issubset(s1)) 表示判断s2,s1是否为子集的关系
B是A的子集
个集合是否是另一个集合的超集
可以调用方法issuperset进行判断
A是B的超集
两个集合是否没有交集
可以调用方法isdisjoint进行判断

1
2
3
4
5
6
7
s1={10,20,30,40,50,60}
s2={10,20,30,40}
s3={10,20,90}
print(s2.issubset(s1))
#True
print (s3.issubset(s1))
#False
1
2
3
#集合生成式
s={i*i for i in range (10)}
print (s)

字符串

字符串
·在Python中字符串是基本数据类型,是一个不可变的字符序列
·什么叫字符串驻留机制呢?
·仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量

字符串的驻留机制

字符串的驻留机制对标准的字符串而言对于有特殊字符如%(不符合命名规则)则不适用

1
2
3
4
5
6
a='Python'
b="Python"
c='''Python'''
print (a,id (a))
print (b,id(b))
print (c,id(c))
1
2
3
Python 2947153397168
Python 2947153397168
Python 2947153397168

·驻留机制的几种情况(交互模式)
·字符串的长度为0或1时
·符合标识符的字符串
字符串只在编译时进行驻留,而非运行时
·[-5,256]之间的整数数字
·字符串驻留机制的优缺点
·当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁
的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是
会比较影响性能的。
在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()
方法是先计算出所有字符中的长度,然后再拷贝,只new一次对象,效率要比"+"效率高

字符串的查询操作的方法

index()查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
rindex()查找子串substr.最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError
find()查找子串substr?第一次出现的位置,如果查找的子串不存在时,则返回-1
rfind()查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1

1
2
3
4
5
s='hello,hello'
print (s.index ('lo')) #3
print (s.find('lo'))#3
print (s.rindex('lo'))#9
print (s.rfind ('lo')) #9

字符串的大小写转换操作的方法

upper()把字符串中所有字符都转成大写字母
lower()把字符串中所有字符都转成小写字母
swapcase()把字符串中所有大写字母转成小写字母,把所有小写字母都转成大写字母
capitalize()把第一个字符转换为大写,把其余字符转换为小写
title()把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写

1
2
3
4
5
6
7
8
9
s='hello,python'
a=s.upper()#转成大写之后,会产生一个新的字符串对象
print (a,id(a))
print(s,id(s))
b=s.lower()#转换之后,会产生一个新的字符串对象
print (b,id(b))
print(s,id(s))
print (b==s) #内容相等
print(b is s)#False id不相等

字符串对齐

center()居中对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则则返回原字符串
ljust()左对齐,第1个参数指定宽度,第2个尽参数指定填充符,第2个参数是可选的,默认是空格如果设置宽度小于实际宽度则则返回原字符串
rjust()右对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格如果设置宽度小于实际宽度则则返回原字符串
zfill()右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身

1
2
3
4
5
6
7
8
9
10
11
12
13
14
s='hello,Python'#居中对齐’
print (s.center (20,'*'))
#左对齐’
print (s.ljust (20,'*'))
print (s.ljust (10))
print (s.ljust (20))
#右对齐’
print (s.rjust (20,'*'))
print (s.rjust (20))
print (s.rjust (10))
#右对齐,使用0进行填充’’
print(s.zfill(20))
print(s.zfill(10))
print('-8910'.zfill(8))

结果为

1
2
3
4
5
6
7
8
9
10
11
****hello,Python****
hello,Python********
hello,Python
hello,Python
********hello,Python
hello,Python
hello,Python
00000000hello,Python
hello,Python
-0008910
进程已结束,退出代码0

字符串对齐

split()从字符串的左边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表,以通过参数sep指定劈分字符串是的劈分符
通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的子串会单独做为一部分

1
2
3
4
5
6
7
8
9
10
s='hello world Python'
lst=s.split()
print(lst)
s1='hello|world|Python'
print (s1.split(sep='|'))
print (s1.split (sep='|',maxsplit=1))
# ’,’rsplit()从右侧开始劈分’
print(s.rsplit())
print (s1.rsplit('|'))
print (s1.rsplit(sep='|',maxsplit=1))
1
2
3
4
5
6
['hello', 'world', 'Python']
['hello', 'world', 'Python']
['hello', 'world|Python']
['hello', 'world', 'Python']
['hello', 'world', 'Python']
['hello|world', 'Python']

判断字符串操作的方法

isidentifier()判断指定的字符串是不是合法的标识符,isspace()判断指定的字符串是否全部由空白字符组成(回车、换行,水平制表符)
isalpha()判断指定的字符串是否全部由字母组成,isdecimal()判断指定字符串是否全部由十进制的数字组成
isnumeric()判断指定的字符串是否全部由数字组成,isalnum()判断指定字符串是否全部由字母和数字组成

字符串替换/合并

replace()第1个参数指定被替换的子串,第2个参数指定替换子串的字符串,该方法返回替换后得到字符串替换后的字符串,替换前的字符串不发生变化,调用该方法时可以通过第3个参数指定最大替换次数
join()字符串的合并将列表或元组中的字符串合并成一个字符串

1
2
3
4
s='hello,Python'
print (s.replace('Python','Java'))
s1='hello,Python,Python,Python'
print (s1.replace ('Python','Java',2))
1
2
hello,Java
hello,Java,Java,Python
1
2
3
t=('hello','Java','Python')
print('|'.join(t))
print ('*'.join ('Python'))
1
2
hello|Java|Python
P*y*t*h*o*n

字符串的比较操作

运算符>,>=,<,<=,==,!=
比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较
比较原理:两上字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数chr,调用内置函数chr时指定ordinal value可以得到其对应的字符

1
2
3
4
print ('apple'>'app') #True
print('apple'>'banana') #False,相当于97>98>False
print (ord('a'),ord('b'))
print (chr (97),chr (98))
1
2
3
4
True
False
97 98
a b
1
2
3
4
5
6
7
8
9
s='hello,Python'
s1=s[:5]
#由于没有指定起始位置,所以从0开始切
s2=s[6:]#由于没有指定结束位置,所以切到字符串的最后一个元素
print(s1)
print(s2)
print(s[1:5:1])#从1开始截到5(不包含5),步长为1
print(s[::2])#默认从0开始,没有写结束,默认到字符串的最后一个元素,步长为2,两个元素之间的索引间隔为2
print(s[::-1])#默认从字符串的最后一个元素开始,到字符串的第一个元素结束,因为步长为负数
1
2
3
4
5
6
7
hello
Python
ello
hloPto
nohtyP,olleh

进程已结束,退出代码0
1
2
3
4
print ('apple'>'app')#True
print('apple'>'banana')#False,相当于97>98>False
print (ord('a'),ord('b'))
print (chr (97),chr (98))
1
2
3
4
True
False
97 98
a b

==与is的区别,==比较的是value,is比较的是id是否相等

格式化字符串

%作占位符或{}作占位符,{序号}序号对应format数组里的值

1
2
3
4
name='张三'
age=20
print('我叫%s,今年%d岁'%(name,age))
print('我叫{0},今年{1}岁'.format(name,age))
1
2
3
4
5
6
print('%10d'% 99)
#10表示的是宽度
print('%.3f' % 3.1415926) #.3表示是小数点后三位
#同时表示宽度和精度
print('%10.3f' %3.1415926)#一共总宽度为10,小数点后3位
print ('hellohello')

字符串的编码转换

编码:将字符串转换为二进制数据(bytes) 解码:将oytes类型的数据转换成字符串类型

1
2
3
4
5
6
7
8
9
10
11
12
s='天涯共此时'
#编码
print (s.encode (encoding='GBK'))
#在GBK这种编码格中一个中文占两个字节
print(s.encode(encoding='UTF-8'))#在UTF-8这种编辑格式中,一个中文占三个字节
#解码
#byte代表就是一个二进制数据(字节类型的数据)
byte=s.encode (encoding='GBK')
#编码
print(byte.decode(encoding='GBK'))#解码
byte=s.encode (encoding='UTF-8')
print (byte.decode (encoding='UTF-8'))

解码和编码协议要对应

函数

函数的定义与调用

·什么是函数
·函数就是执行特定任和以完成特定功能的一段代码
·为什么需要函数
·复用代码
·隐藏实现细节
·提高可维护性
·提高可读性便于调试
·函数的创建
def
函数名([输入参数]):
函数体
[return xxx]

1
2
3
4
5
6
7
8
9
def calc(a,b):#a,b称为形式参数,简称形参,形参的位置是在函数的定义处
c=a+b
return c
result=calc(10,20)
#10,20称为实际参数的值,简称实参,实参的位置是函数的调用处
print (result)
res=calc(b=10,a=20)
#=左侧的变量的名称称为
print (res)

函数的返回值
(1)如果函数没有返回值【函数执行完毕之后,不需要给调用处提供数据】return可以省略不写
(2)函数的返回值,如果是1个,直接返回类型
(3)函数的返回值,如果是多个,返回的结果为元组

函数的参数定义

函数定义默认值参数,函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参
def fun(a,b=10)只传一个
print (a,b)
b采用默认值函数的调用
fun(100)
30将默认
fun(20,30)
值10替换

个数可变的位置参数

定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数使用*定义个数可变的位置形参

1
2
3
4
5
6
def fun(*args):#函数定义时的可变的位图参数
print (args)
print (args[0])
fun(10)
fun(10,30)
fun(30,405,50)

个数可变的关键字形参

定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参
使用**定义个数可变的关键字形参

1
2
3
4
def fun1 (**args):
print (args)
fun1(a=10)
fun1(a=20,b=30,c=40)

{'a': 10}
{'a': 20, 'b': 30, 'c': 40}
可变的位置参数或者关键字形参,只能是1个;在一个函数的定义过程中,既有个数可变的关键字形参,也有个数可变的位置形参,要求,个数可变的位置形参,放在个数可变的关键字形参之前。def fun3 (**args1,*arg2):

函数参数总结

在函数调用时,将列表中的每个元素都转换为位置实参传入*lst,字典则要**dic

1
2
3
4
5
6
7
8
9
10
11
12
13
def fun(a,b,c):#a,b,c在函数的定义处,所以是形式参数
print ('a=',a)
print ('b=',b)
print ('c=',c)
#函数的调秀
fun(10,20,30)
#函数调用时的参数传递,称为位置传参
lst=[11,22,33]
fun (*lst)
#在函数调用时,将列表中的每个元素都转换为位置实参传入
fun(a=100,c=300,b=200)#函数的调用,所以是关键字实参
dic={'a':112,'b':221,'c':334}
fun (**dic)
1
2
3
4
5
6
def fun2(*args):#个数可变的位置形参
print (args)
def fun3(**args2):#个数可变的关键字形参
print (args2)
fun2(10,20,30,40)
fun3(a=10,b=20,d=90)

结果为(10, 20, 30, 40) {'a': 10, 'b': 20, 'd': 90}
def fun4(a,b,*,c,d):#从*之后的参数,在函数调用时,只能采用关键字参数传递

变量的作用域

·程序代码能访问该变量的区域
·根据变量的有效范围可分为局部变量:在函数内定义并使用的变量,只在函数内部有效。局部变量使用global声明,这个变量
就会就成全局变量。全局变量:函数体外定义的变量,可作用于函数内外

1
2
3
4
5
6
7
def fun3():
global age
#函数内部定义的变量,局部变量,局部变量使用g1oba1声明,这个变量实际上就变成了全局变量
age=20
print (age)
fun3()
print (age)

递归

·什么是递归函数如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数
·递归的组成部分,递归调用与递归终止条件
递归的调用过程:每递归调用一次函数,都会在栈内存分配一个栈帧,每执行完一次函数,都会释放相应的空间
递归的优缺点:缺点:占用内存多,效率低下;优点:思路和代码简单

1
2
3
4
5
6
def fac (n):
if n==1:
return 1
else:
return n*fac (n-1)
print (fac (6))

return fib(n-2)+fib(n-1)中的n-2不能写成n

1
2
3
4
5
6
7
8
def fib (n):
if n==1:
return 1
elif n==2:
return 1
else:
return fib(n-2)+fib(n-1)
print (fib (6))
1
2
for i in range(2,7):
print(fib(i))

BUG

Bug的常见类型
粗心导致错误的自查宝典
1.漏了末尾的冒号,如if语句,循环语句,else子句等
2缩进错误,该缩进的没缩进,不该缩进的瞎缩进
3把英文符号写成中文符号,比如说:引号,冒号,括号
4.字符串拼接的时候,把字符串和数字拼在一起
5.没有定义变量,比如说while的循环条件的变量
6.“==”比较运算符和”=”赋值运算符的混用

try-except

1
2
3
4
5
6
7
8
9
10
11
12
13
try:
可能会
出异常
的代码
except Exception1:
异常处
理代码
except Exception2:
异常处
理代码
except BaseException:
异常处
理代码

其中BaseException包含了所有的报错类型可用以下代码打印BUG类型,也可以直接except:

1
2
except BaseException as e:
print('出错了',e)

try-except-else

try-except..else结构
如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块

try..except..else.finally

finally块无论是否发生异常都会被执行,能常用来释放try块中申请的资源

异常类型

ZeroDivisionError 除(或取模)零(所有数据类型)
IndexError 序列中没有此索引(index)
KeyError 映射中没有这个键
NameError 未声明/初始化对象(没有属性)
SyntaxError Python语法错误
ValueError 传入无效的参数

断点

程序运行到此处,暂时挂起,停止执行。此时可以详细观察程序的运行情况,方便做出进一步的判断

类与对象

·类:类别,分门别类,物以类聚,人类,鸟类,动物类,植物类…
·类是多个类似事物组成的群体的统称。能够帮助我们快速理解和判断事物的性质。
·数据类型不同的数据类型属于不同的类使用内置函数查看数据类型

1
2
3
4
5
6
print (type(100))
<classint'>
print (type(99))
<class’int'>
print (type(520))
<class 'int'>

·对象:100、99、520都是int类之下包含的相似的不同个例,这个个例专业数语称为实例或对象

创建类

类命名:每个单词的首字母大写,其余小写

1
2
3
4
5
6
class Student:#Student为类的名称(类名)由一个或多个单词组成,每个单词的首字母大写,其余小写
pass
#Python中一切皆对象Student是对象吗?内存有开空间吗?
print (id(Student))#2769050434400
print (type(Student))#<class type'>
print (Student)#<class'main_.Student'>

类的组成:类属性,实例方法,静态方法,类方法且默认参数不能修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Student:#Student为类的名称(类名)由一个或多个单词组成,每个单词的首字母大写,其余小写
native_pace='吉林'
#直接写在类里的变量,称为类属性
def __init__(self,name,age):
self.name=name
#self.name称为实体属性,进行了一个赋值的操作,将局部变量的name的值赋给实体属性
self.age=age
#实例方法
def eat (self):
print('学生在吃饭..')
#静态方法
@staticmethod
def method ():
print('我是静态方法')

#类方法
@classmethod
def cm(cls):
print('我是类方法')

代码中def eat (self):的self代表自身,即必须传入Student对象

对象的创建

对象的创建
对象的创建又称为类的实例化,意义:有了实例,就可以调用类中的内容
语法:
实例名=类名 以类名Student为例,stu1=Student('zhang',56) 再调用类中的实例方法stu1.eat()也可表示为Student.eat(stu1)格式为:类名.方法名(类的对象名)-->实际上就是方法定义处的self

类属性

类属性的使用方式:类.类属性名

1
2
3
4
5
6
stu1=Student('zhang',56)  #创建对象
stu2=Student('zhang2',58)
Student.native_pace='tianj' #修改类属性名
print(stu1.native_pace)
print(stu2.native_pace)
print(Student.native_pace)

·类属性:类中方法外的变量称为类属性,被该类的听有对象所共享;类方法:使用@classmethod修饰的方法,使用类名直接访问的方法;静态方法:使用@staticmethod修饰的主法,使用类名直接访问的方法
类方法:如果方法需要该类的信息,用 @classmethod 对其进行装饰
定义:使用装饰器@classmethod。第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法);
静态方法:静态方法并不是真正意义上的类方法,它只是一个被放到类里的函数而已。
定义:使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法中不能使用类或实例的任何属性和方法;
参考
还有一种结构类似自定义函数,1. 实例方法
类中的所有方法,如果第一个参数是 self,就是 instance method, self 是创建的类实例,实例方法与实例即对象相关。,往往需要通过对象调用,
(self 可以改成别的名称,但使用 self 是convention,self 是类实例, )

动态绑定属性和方法

Python:是动态语言,在创建对象之后,可以动态地绑定属性和方法。如果想给对象stu1添加性别属性为女而stu2保持不变,则可为stu2动态绑定性别属性。stu1.gender='女'#动态绑定性别
动态绑定方法

1
2
3
4
def show():
print('我是一函数')
stu1.show=show #动态绑定方法
stu1.show()

面向对象的三大特征

封装:提高程序的安全性
·将数据(属性)和行为(方法)
包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。
·在Pyho中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个“”。
·继承:提高代码的复用性
·多态:提高程序的可扩展性和可维护性
在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个“__”。不能直接用stu1.__age访问,需要#在类的外部可以通过_Student__age进行访间,具体是由print(dir(stu))查看的

继承

继承动物
语法格式:class子类类名(父类1,父类2..):
如果一个类没有继承任何类,则默认继承object
Python支持多继承定义子类时,必须在其构造函数中调用父类的构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Person(object): #object默认无继承
def __init__(self,name,age):
self.name=name
self.age=age
def info(self):
print('姓名:{0},年龄:{1}'.format(self.name,self.age))
#定义子类
class Student (Person): #继承Person类
def __init__(self,name,age,score):
super().__init__(name,age) #从Person类中调用方法
self.score=score
#测试
stu=Student ('Jack',20,'1001')
stu.info()

实例方法可直接继承stu.info() ,可多继承如class C(A,B):同时继承A和B

方法重写

如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重新编写子类重写后的方法中可以通过super().xx调用父类中被重写的方法
如果在Student (Person)中添加和Person一样的方法,则对其中的实例可打印新的score

1
2
3
4
5
6
7
class Student (Person):  #继承Person类
def __init__(self,name,age,score):
super().__init__(name,age) #从Person类中调用方法
self.score=score
def info(self):
super().info() #调用父类中被重写的方法
print(self.score)

object类

object类是所有类的父类,因此所有类都有object类的属性和方法,内置函数dir()可以查看指定对象所有属性
Object有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对__str__()进行重写

1
2
3
4
5
class Student():
pass
stu=Student()
print (dir(stu))
print (stu)

Student类默认继承object类,而通过运行上述代码可得结果为

1
2
3
4
5
6
#print (dir(stu))的结果如下  
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
#print (stu)的结果如下
<__main__.Student object at 0x000002A892EC70D0>
#stu=Student时返回的结果:
<class '__main__.Student'>

故可知object类中默认含有__str__()方法,默认返回对象的描述,可通过重写__str__()方法改变print (stu)的返回结果

1
2
3
4
5
6
7
8
9
10
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '我的名字是{0},今年{1}岁'.format(self.name, self.age)
# pass
stu=Student('zhang','3')
print (dir(stu))
print (stu)

运行上述代码返回print (stu)结果我的名字是zhang,今年3岁

多态

简单地说,多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Animal (object):
def eat (self):
print('动物会吃')
class Dog (Animal):
def eat (self):
print('狗吃骨头...')
class Cat (Animal):
def eat (self):
print('猫吃鱼...')
class Person():
def eat (self):
print('ren')
def fun1(abc):
abc.eat()
fun1(Person())
fun1(Dog())
fun1(Cat())
fun1(Animal())

fun1中传入哪个对象就调用该对象所在类中的方法。且eat()方法本身有Print输出所以不需要print(fun1(Dog()))
静态语言(Java)和动态语言(Python)关于多态的区别
静态语言实现多态的三个必要条件:继承,方法重写,父类引用指向子类对象
动态语言的多态崇尚“鸭子类型”当看到一只鸟走起来像鸭子、游泳起来像鸭子收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。
特殊属性:
dict()获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法:
len()通过重写1en方法,让内置函数1en的参数可以是自定义类型
add()通过重写add方法,可使用自定义对象具有“+”功能
new()用于创建对象
init()对创建的对象进行初始化
dir()可以用来查看属性和方法

1
2
3
4
5
6
7
8
9
10
class A:
pass
class B:
pass
class C(A,B):
def __init__(self,name):
self.name=name
#创建C类的对象
x=C('Jack')
print(x.__dict__)

运行上述代码可输出#实例对象x的属性字典为{'name': 'Jack'}

__add__方法

__add__方法可以用来表示+号

1
2
3
4
5
6
a=20
b=100
c=a+b
d=a.__add__(b)
print(c) #120
print(d) #120

也可以定义在类中使原本两个不能连接的属性相+

1
2
3
4
5
6
7
8
9
10
11
12
class Student:
def __init__(self,name):
self.name=name
def __add__(self,other):
return self.name+other.name
stu1=Student('张三')
stu2=Student('李四')
s=stu1+stu2
#实现了两个对象的加法运算(因为在Student类中编写add()特殊的方法)
print (s)
s=stu1.__add__(stu2)
print (s)

结果为张三李四
len可以用于打印创建对象的长度

1
2
3
4
lst=[11,22,33,44]
print(len(lst))#1en是内容函数len 4
print (lst.__len__()) #4
print (len(stu1)) #2

new__方法和__init

创建Person类的实例对象p1时会调用一次init方法和new方法,其中new方法的三个参数是默认规定的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person(object):
def __new__(cls,*args,**kwargs):
print('new被调用执行了,cls的id值为{0}'.format(id(cls))) #id:9360
obj=super().__new__(cls)
print('创建的对象的id为:{0}'.format(id(obj))) #id:7104
return obj
def __init__(self,name,age):
print('init被调用了,self的id值为:{0}'.format(id(self))) #id:7104
self.name=name
self.age=age
print('object这个类对象的id为:{0}'.format(id(object))) #id:3232
print('Person这个类对象的id为:{0}'.format(id(Person))) #id:9360
#创建Person类的实例对象
p1=Person('张三',20)
print('p1这个Person类的实例对象的id:{0}'.format(id(p1))) #id:7104

执行p1=Person('张三',20)时相当于把Person传入了cls;创建新的对象obj有一个新的id然后返回传入到self,p1与self一致故三者id相同。

类的浅拷贝与深拷贝

变量的赋值操作

·只是形成两个变量,实际上还是指向同一个对象

1
2
3
4
5
6
7
8
9
10
11
12
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self,cpu,disk):
self.cpu=cpu
self.disk=disk
cpu1=CPU()
cpu2=cpu1
print (cpu1)
print (cpu2)

运行上述代码后输出地址相同

浅拷贝

·Python:拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝
因此,源对象与拷贝对象会引用同一个子对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self,cpu,disk):
self.cpu=cpu
self.disk=disk
cpu1=CPU()
disk1=Disk()#创建一个硬盘类的对象
computer=Computer(cpu1,disk1)#创建一个计算机类的对象
#浅拷贝
import copy
computer2=copy.copy (computer)
print (computer,computer.cpu,computer.disk)
print (computer2,computer2.cpu,computer2.disk)

以上代码中computer=Computer(cpu1,disk1)的cpu1和disk1都是实例对象,之前用的基本都是'cpu1'加了引号的字符串对象,调用两个子实例对象打印输出的地址不变(引用同一个子对象),而computer2和computer的地址会变;若用了'cpu1'加了引号的字符串对象则无法调用浅拷贝。且computer2.cpu与computer.cpu的输出地址不同

深拷贝

·使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对
和拷贝对象所有的子对象也不相同
将代码改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self,cpu,disk):
self.cpu=cpu
self.disk=disk
cpu1=CPU()
disk1=Disk()#创建一个硬盘类的对象
computer=Computer(cpu1,disk1)#创建一个计算机类的对象
#深拷贝
import copy
computer3=copy.deepcopy (computer)
print (computer,computer.cpu,computer.disk)
print (computer3,computer3.cpu,computer3.disk)

得到结果为<__main__.Computer object at 0x0000020C48847EB0> <__main__.CPU object at 0x0000020C48847FD0> <__main__.Disk object at 0x0000020C48847EE0><__main__.Computer object at 0x0000020C48847D00> <__main__.CPU object at 0x0000020C48847700> <__main__.Disk object at 0x0000020C48875EA0>可以看到所有id都发生了变化,也就是深拷贝不仅仅只拷贝框架,还把实例对象也拷贝了,而每次拷贝ID都会变所以最后ID不相同

模块

模块英文为Modules
·函数与模块的关系:一个模块中可以包含N多个函数
·在Python中一个扩展名为.py的文件就是一个模块
使用模块的好处:方便其它程序和脚本的导入并使用,避免函数名和变量名冲突,提高代码的可维护性,提高代码的可重用性
一个项目可以包含很多模块用import导入模块,以自带的math模块为例

1
2
3
4
5
6
7
8
9
import math#关于数学运算
print (id(math))
print(type (math))
print (math)
print (math.pi)
print (dir(math))
print (math.pow (2,3),type (math.pow (2,3)))
print (math.ceil(9.001))
print(math.floor(9.9999))

结果为

1
2
3
4
5
6
7
8
2072650326608
<class 'module'>
<module 'math' (built-in)>
3.141592653589793
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'lcm', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'nextafter', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc', 'ulp']
8.0 <class 'float'>
10
9

也可以只导入math中的一个方法比如pi方法,用from math import pi此时单独导入了pi没有导入math所以只能使用print (pi)而不能用print(math.pi)
再比如新建py命名为calc如下

1
2
3
4
def add (a,b):
return a+b
def div (a,b):
return a/b

则可使用调用加法运算

1
2
import caluc 
print(caluc.add(10,5))

以主程序方式运行

·以主程序形式运行,在每个模块的定义中都包括一个记录模块名称的变量name,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其它程序中执行,那么它可能在解释器的顶级模块中行。顶级模块的__name__变量的值为__main__

1
2
if __name__=='__main__':
print('只有运行模块主体Py程序才会显示')

在其他py文件中调用模块则不会显示

Python中的包

·Python中的包:包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录

作用:
·代码规范
·避免模块名称冲突
·包与目录的区别
·包含_init_py文件的目录称为包
·目录里通常不包含_init_py文件
·包的导入
import包名.模块名
注意包名不要用纯数字,例如包名p1下有ma.py和mb.py,ma.py下存在a=10则可以先引入import p1.ma然后print(p1.ma.a)import p1.ma as ma这样就可以精简包名下面模块的名称print(ma.a)
使用import导入只能导入包名和模块名。使用from....import可以导入包,模块,函数,变量
Python中常用的内置模块
sys:与Python解释器及其环境操作相关的标准库
time:提供与时间相关的各种函数的标准库
os:提供了访问操作系统服务功能的标准库
calendar:提供与日期相关的各种函数的标准库
urllib:用于读取来自网上(服务器)的数据标准库
json:用于使用JS0N序列化和反序列化对象
re:用于在字符串中执行正则表达式匹配和替换
math:提供标准算术运算函数的标准库
decimal:用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算
logging:提供了灵活的记录事件、错误、警告和调试信息等目志信息的功能

1
2
import urllib.request #调用urllib下面的request模块常用于爬虫
print(urllib.request.urlopen('http://www.baidu.com').read())

跳转到urllib发现跳转到了__init.py__因此可以判断这个是包而不是模块,以上程序可以读取百度返回的值

第三方模块应用

pip install 模块名执行后发现报错Fatal error in launcher: Unable to create process using '"D:\python\python.exe" "E:\python\Scripts\pip.exe" install schedule': ???????????使用python -m pip install -U pip解决!比如安装完schedule后即可调用;run_pending:运行所有可以运行的任务

1
2
3
4
5
6
7
8
import schedule
import time
def job():
print('哈哈')
schedule.every(3).seconds.do(job)
while True:
schedule.run_pending()
time.sleep(1)

会每隔三秒执行一次哈哈

常见的字符编码格式

·Python的解释器使用的是Unicode(内存)
·.py文件在磁盘上使用UTF-8存储(外存)
用encoding=xxx可更改编码格式
pcharm新建文件.txt默认编码格式为UTF-8
新建文件a.txt并在py中加入以下代码

1
2
3
file=open('a.txt', 'r')
print(file.readlines())
file.close() #关闭资源

发现报错UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 2: illegal multibyte sequence
文件解码不对,默认用gbk解码实际文件UTF-8,将第一行代码调整为file=open('a.txt', 'r',encoding='utf-8')即可
r以只读模式打开文件,文件的指针将会放在文件的开头
W以只写模式打开文件,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头
a以追加模式打开文件,如果文件不存在则创建,文件指针在文件开头,如果文件存在,则在文件末尾
b以二进制方式打开文件,不能单独使用,需要与共它模式一起使用,rb,或者wb
+以读写方式打开文件,不能单独使用,需要与其它模式一起使用,a+,不写加可能会是只读只写
创建文件示例:

1
2
3
file=open ('b.txt','w')
file.write('Python')
file.close()

使用追加模式在b.txt文件中写另外两个Python

1
2
3
file=open ('b.txt','a')
file.write('Pythonzhuijia')
file.close()

此时b.txt变为PythonPythonzhuijia

with

with语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确的关闭,以此来达到释放资源的目的,就不用写close了

1
2
with open('b.txt','r') as file:
print(file.read())

遵守了上下文管理协议,实现了进入时调用__enter__方法,退出时调用__exit__方法

1
2
3
4
5
6
7
8
9
10
class MyContentMgr (object):
def __enter__(self):
print('enter方法被调用执行了')
return self
def __exit__(self,exc_type,exc_val,exc_tb):
print('exit方法被调用执行了')
def show (self):
print('show方法被调用执行了')
with MyContentMgr() as file:
file.show()

结果:
enter方法被调用执行了
show方法被调用执行了
exit方法被调用执行了
文件复制方法

1
2
3
with open ('logo.png','rb') as src_file:
with open ('copy2logo.png','wb') as target_file:
target_file.write(src_file.read())

os模块

os模块是Python内置的与操作系统功能和文件系统相关的模块
该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样。
os模块与os.path模块用于对目录或文件进行操作

os模块操作目录

getcwd()返回当前的工作目录
listdir(path)返回指定路径下的文件和目录信息
mkdir(path[,mode])创建目录
makedirs(path1/path2...[,mode])创建多级目录
rmdir(path)删除目录
removedirs(path1/path2......)删除多级目录
chdir(path)将path设置为当前工作目录
其中listdir(path)用于找当前目录,../上级目录

ospath模块操作目录

abspath(path) 用于获取文件或目录的绝对路径
exists(path) 用于判断文件或目录是否存在,如果存在返回True否则返回False
join(path,name)将目录与目录或者文件名拼接起来
splitext()分离文件名和扩展名
basename(path)从一个目录中提取文件名
dirname(path)从一个路径中提取文件路径,不包括文件名
isdir(path)用于判断是否为路径
打印当前目录下.x结尾的文件

1
2
3
4
5
6
import os
path=os.getcwd()
lst=os.listdir(path)
for file in lst:
if file.endswith('.txt'):
print(file)

使用目录树生成器os.walk()遍历当前目录

1
2
3
4
5
6
7
8
import os
path=os.getcwd()
lst_files=os.walk(path)
for dirpath, dirnames, filenames in lst_files:
print(dirpath) #打印当前路径
print(dirnames) #打印当前路径下存在的文件名
print(filenames) #打印当前路径下所有文件
print('------------')

学生信息管理系统

遇到continue报错的情况是因为continue没有放在while True:下面,缩进一下即可
'\n' 的意思是:回车换行,调用save()函数要与while True:同级,因为continue语句的作用是跳过本次循环体中余下尚未执行的语句,立即进行下一次的循环条件判定,可以理解为仅结束本次循环。
eval函数是Python中内置的一个函数,用于将字符串作为Python代码进行执行,并返回执行后的结果。eval函数主要有以下作用:

  1. 计算字符串表达式
    eval函数可以计算字符串类型的数学表达式。例如,将字符串"1+2"作为参数传入eval函数,会返回3。
  2. 执行动态的Python代码
    eval函数可以执行动态的Python代码,例如动态生成一段Python代码并执行。这对于需要在运行时根据不同条件进行代码逻辑分支的应用场景非常有用。
  3. 提供交互式控制台
    eval函数可以将用户输入的字符串作为Python代码进行执行,从而实现一个简单的交互式控制台。这对于一些较为简单的应用场景非常有用,例如一个简单的计算器程序。
    需要注意的是,由于eval函数会执行任意字符串作为Python代码,因此在使用时需要非常谨慎,确保不会执行恶意代码。为了避免安全问题,建议在不确定字符串来源的情况下,不要使用eval函数。
    python里 {0:30}是什么意思?{0:30}中的0是一个序号,表示格式化输出的第0个字符,依次累加;{0:30}中的30表示输出宽度约束为30个字符;{0:30}中的^表示输出时居中对齐,若宽度小于字符串的实际宽度,以实际宽度输出;
    以下为代码,代码中的数据显示还可以优化一下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
filename='student.txt'
import os
def menm():
print('====学生信息管理====')
print('--功能菜单--')
print('\t\t\t\t\t\t1.录入学生信息')
print('\t\t\t\t\t\t2.查找学生信息')
print('\t\t\t\t\t\t3.删除学生信息')
print('\t\t\t\t\t\t4.修改学生信息')
print('\t\t\t\t\t\t5.排序')
print('\t\t\t\t\t\t6.统计学生总人数')
print('\t\t\t\t\t\t7.显示所有学生信息')
print('\t\t\t\t\t\t0.退出')
def main():
while True:
menm()
choice = int(input('请选择'))
if choice in [0, 1, 2, 3, 4, 5, 6, 7]:
if choice == 0:
answer = input('您确定要退出系统吗?y/n')
if answer == 'y' or answer == 'Y':
print('谢谢您的使用!!')
break # 退出系统
else:
continue
elif choice==1:
insert()
elif choice == 2:
search()
elif choice==3:
delete()
elif choice==4:
modify()
elif choice==5:
sort()
elif choice==6:
total()
elif choice==7:
show()
def insert():
student_list=[]
while True:
id=int(input('请输入ID如1001'))
if not id:
break
name=input('请输入姓名')
if not name:
break
try:
englist = int(input('请输入英语成绩:'))
python = int(input('请输入Python成绩:'))
java = int(input('请输入Java成绩:'))
except:
print('输入无效,不是整数类型,请重新输入')
continue
# 将录入的学生信息保存到字典中
student = {'id': id, 'name':name,'english':englist,'python':python, 'java':java}
# 将学生信息添加到列表中
student_list.append(student)
answer = input('是否继续添加?y/n\n')
if answer == 'y':
continue
else:
break
# 调用save()函数
save(student_list)
print('学生信息录入完毕!!')
def save(lst):
try:
stu_txt=open(filename,'a',encoding='utf-8')
except:
stu_txt = open(filename,'w', encoding='utf-8')
for item in lst:
stu_txt.write(str(item)+'\n')
stu_txt.close()

def search():
# student_query=[]
while True:
if os.path.exists(filename):
mode=input('请输入查询方式1为ID,2为姓名')
if mode=='1':
id=int(input('请输入学生ID'))
elif mode=='2':
name=input('请输入学生name')
else:
print('输入错误重新输入')
continue
with open(filename, 'r', encoding='utf-8') as rfile:
student = rfile.readlines()
for item in student:
d = dict(eval(item))
if id != '':
if d['id'] == id:
print(d)
elif name != '':
if d['name'] == name:
print(d)
answer=input('是否继续查询y/n')
if answer=='y':
continue
else:
break

else:
print('暂未查到学生信息')
return
def delete():
while True:
student_id=int(input('请输入要删除的ID:'))
if student_id!='':
if os.path.exists(filename):
with open(filename,'r',encoding='utf-8') as file:
student_old=file.readlines()
else:
student_old=[]
flag = False # 标记是否刷除
if student_old:
with open(filename,'w',encoding='utf-8') as wfile:
d={}
for item in student_old:
d=dict(eval(item))
if d['id']!=student_id:
wfile.write(str(d)+'\n')
else:
flag=True
if flag:
print(f'{student_id}学生信息已被删除')
else:
print(f'没有找到{student_id}')
else:
print('无学生信息')
break
show()
answer=input('是否继续删除?y/n\n')
if answer=='y':
continue
else:
break





def modify():
show()
if os.path.exists(filename):
with open(filename,'r',encoding='utf-8') as rfile:
student_old=rfile.readlines()
else:
return #退出If
student_id=int(input('请输入要修改的学员ID:'))
with open(filename,'w',encoding='utf-8') as wfile:
d={}
for item in student_old:
d=dict(eval(item))
if d['id']==student_id:
print('找到需要修改的学生了')
while True:
try:
d['name'] =input('请输入姓名:')
d['english'] = input('请输入英语成绩:')
d['python'] = input('请输入Python成绩:')
d['java'] = input('请输入Java成绩:')
break
except:
print('输入有误')
wfile.write(str(d) + '\n')
print('已修改')
else:
wfile.write(str(d) + '\n')
answer = input('是否继续修改其它学生信息?y/n\n')
if answer =='y':
modify()



def sort():
show()
if os.path.exists(filename):
with open(filename,'r',encoding='utf-8') as rfile:
student_list=rfile.readlines()
student_new=[]
for item in student_list:
d=dict(eval(item))
student_new.append(d)
asc_or_desc = input('请选择0.升序1.降序:')
if asc_or_desc == '0':
asc_or_desc_bool = False
elif asc_or_desc == '1':
asc_or_desc_bool = True
else:
print('您的输入有误,请重新输入')
sort()
mode = input('请选择排序方式(1.按英语成绩排序2.按Python成绩排序3.按Java成绩排序0.按总成绩排序')
if mode =='1':
student_new.sort(key=lambda x:int(x['english']), reverse=asc_or_desc_bool)
elif mode =='2':
student_new.sort(key=lambda x: int(x['python']), reverse=asc_or_desc_bool)
elif mode == '3':
student_new.sort(key=lambda x: int(x['java']), reverse=asc_or_desc_bool)
elif mode == '0':
student_new.sort(key=lambda x: int(x['english'])+int(x['python'])+int(x['java']), reverse=asc_or_desc_bool)
else:
print('输入有误请重新输入')
sort()

else:
print('学生信息不存在')
for i in student_new:
print(str(i)+'\n')

def total():
if os.path.exists(filename):
with open(filename,'r',encoding='utf-8') as rfile:
students=rfile.readlines()
if students:
print(f'共有{len(students)}人')
else:
print('还未保存学生信息')

else:
print('暂未保存学生信息')
def show():
if os.path.exists(filename):
with open(filename,'r',encoding='utf-8') as rfile:
student=rfile.readlines()
for item in student:
print(item)
else:
print('暂未保存过数据')
if __name__=='__main__': #表示仅能在本模块中调用
main()

Pyinstaller模块打包exe

安装pip install Pylnstaller,然后pyinstaller -F 路径,日志中能查看生成的exe文件目录

其他项目中用到的方法

pythonQT

strip()方法

Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。str.strip( '0' ); # 去除首尾字符 0
注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。

splitlines()方法

Python splitlines() 按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
str1 = 'ab c\n\nde fg\rkl\r\n'输出['ab c', '', 'de fg', 'kl']
'\r' 回车,回到当前行的行首,而不会换到下一行,如果接着输出的话,本行以前的内容会被逐一覆盖;
'\n' 换行,换到当前位置的下一行,而不会回到行首;
通常多行使用

split()方法

Python split() 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则分隔 num+1 个子字符串
语法
split() 方法语法通常单行使用:
str.split(str="", num=string.count(str)).

if xxx.strip()函数的使用

1
2
3
4
5
6
7
8
a = '            \n this is a test file  \t '  #句子有空格和换行以及回车
b = ' \t \n' #句子除了换行空格和回车外没有其他字符
if a.strip(): #如果a.strip()的值为真,打印a,否则为假不打印。
print(a)
if b.strip(): #如果b.strip()的值为真打印b,为假不打印
print(b)

>>> this is a test file

参考

for循环break、continue

参考
continue在for循环中的作用是跳出本次循环,进行下一次循环;break会跳出循环,不会执行break后面的一切代码

.Session()

requests.session的作用:自动处理cookie,即 下一次请求会带上前一次的cookie

自定义函数的注意

python函数中带具体值的形参放函数定义的最后面

python暂停语句

1
2
import pdb
pdb.set_trace()