前言:本篇文章是作者在B站学习python马士兵视频的笔记,之前章节的内容可参考https://blog.csdn.net/qq_43511094/article/details/113062435
或https://blog.csdn.net/weixin_46860149/article/details/118232264
视频传送门:https://www.bilibili.com/video/BV1wD4y1o7AS
十一章 异常
python异常处理机制
python中常见的异常类型
# print (10/0) #ZeroDivisionError
lst = [11, 22, 33, 44]
# print(lst[4])#IndexError索引从0开始
dic = {'name': '张三', 'age': 20}
# print(dic['gender']) #KeyError
# print (num) # NameError
# int a=20 #SyntaxError python中的变量没有数据类型
a = int('hello') # ValueError
traceback模块的使用
pycharm开发环境的调试
十二章 类与对象
定义python中的类
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(): # 静态方法中不能加self
print('我使用了staticmethod进行修饰,所以我是静态方法')
# 类方法
@classmethod
def cm(cls):
print('我是类方法,因为我使用了classmethod进行修饰')
# 类之外定义的叫函数,类里定义的叫方法
def drink():
print('喝水')
对象的创建
# 创建Student类的对象
stu1 = Student('张三', 20)
stu1.eat() # 对象名.方法名()
print(stu1.name)
print(stu1.age)
Student.eat(stu1) # 第二种调用方式, 类名.方法名(类的对象)-->实际上就是方法定义处的self
# 输出
'''学生在吃饭...
张三
20
学生在吃饭...'''
类属性、类方法、静态方法的使用方式
# 类属性的使用方式
print(Student.native_pace) # 访问类属性
stu1 = Student('张三', 20)
stu2 = Student('李四', 30)
print(stu1.native_pace)
print(stu2.native_pace)
'''输出:
吉林
吉林
吉林'''
#类方法的使用方式
Student.cm() # 实例方法需要传实例对象,而类方法通过类名来调用
'''输出: 我是类方法,因为我使用了classmethod进行修饰'''
#静态方法的使用方式
Student.method() # 没有默认参数,也是通过类名来调用
'''输出: 我使用了staticmethod进行修饰,所以我是静态方法'''
动态绑定属性和方法
class Student: # Student为类的名称(类名)由一个或多个单词组成,每个单词的首字母大写,其余小写
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(self.name + '在吃饭')
stu1 = Student('张三', 20)
stu2 = Student('李四', 30)
# 为stu1动态绑定性别属性
stu1.gender = '女'
print(stu1.name, stu1.age, stu1.gender)
'''输出: 张三 20 女'''
print(stu2.name, stu2.age)
'''输出: 李四 30'''
# 一个Student类可以创建N多个Student类的实例对象,每个实体对象的属性值不同
def show():
print('定义在类之外的,称函数')
# 为stu1动态绑定方法
stu1.show = show
stu1.show()
十三章 面向对象
面向对象的三大特性----封装、继承、多态
封装的实现方式
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age # 年龄不希望在类的外部被使用,所以加了两个_
def show(self):
print(self.name, self.__age)
stu = Student('张三', 20)
stu.show()
# 在类外使用name
print(stu.name)
# print(stu.__age) 访问不了
print(stu._Student__age) # 在类的外部可以通过 _类名__属性名 进行访问,但是不建议
继承及其实现方式
class Person(object): # Person类继承object类
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person): # Student类继承Person类
def __init__(self, name, age, stu_no):
super().__init__(name, age) # 使用super调用父类的方法
self.stu_no = stu_no
class Teacher(Person): # Teacher类继承Person类
def __init__(self, name, age, teachofyear):
super().__init__(name, age)
self.teachofyear = teachofyear
stu = Student('张三', 20, '1001')
teacher = Teacher('李四', 30, 10)
stu.info()
teacher.info()
'''输出:
张三 20
李四 30'''
#多继承
class A(object):
pass
class B(object):
pass
class C(A,B):
pass
方法重写
class Person(object): # Person类继承object类
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person): # Student类继承Person类
def __init__(self, name, age, stu_no):
super().__init__(name, age)
self.stu_no = stu_no
def info(self): # 重写父类的方法
super().info() # 先执行父类的方法
print(self.stu_no)
class Teacher(Person): # Teacher类继承Person类
def __init__(self, name, age, teachofyear):
super().__init__(name, age)
self.teachofyear = teachofyear
def info(self):
super().info() # 先执行父类的方法
print('教龄', self.teachofyear)
stu = Student('张三', 20, '1001')
teacher = Teacher('李四', 30, 10)
stu.info()
teacher.info()
'''输出:
张三 20
1001
李四 30
教龄 10'''
Object类
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '我的名字是{0},今年{1}岁'.format(self.name, self.age)
stu = Student('张三', 20)
print(dir(stu))
print(stu) # 默认会调用__str__()这样的方法
'''输出:
['__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__', 'age', 'name']
我的名字是张三,今年20岁'''
多态
python是动态语言,它只关心这个类有没有相应的方法,像上面的Person类没有继承Animal类,但它有eat()方法
这是与java等静态语言不一样的地方
特殊方法和特殊属性
特殊属性
class A(object):
pass
class B(object):
pass
class C(A, B):
def __init__(self, name, age):
self.name = name
self.age = age
# 创建C类的对象
x = C('jack', 20) # x是C类的一个实例对象
print(x.__dict__) # 实例对象的属性字典
print(C.__dict__) # 类的属性字典
print('--------')
print(x.__class__) # 输出对象所属的类
print(C.__bases__) # 输出C类的父类类型的元素
print(C.__mro__) # 类的层次结构
print(A.__subclasses__()) # 子类的列表
'''输出:
{'name': 'jack', 'age': 20}
{'__module__': '__main__', '__init__': <function C.__init__ at 0x000001D9042EBDC0>, '__doc__': None}
--------
<class '__main__.C'>
(<class '__main__.A'>, <class '__main__.B'>)
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
[<class '__main__.C'>]
'''
特殊方法
class Student:
def __init__(self, name):
self.name = name
def __add__(self, other):
return self.name + other.name
def __len__(self):
return len(self.name)
stu1 = Student('张三')
stu2 = Student('李四')
s = stu1 + stu2 # 实现了两个对象的加法运算(因为在Student类中编写_add__()特殊的方法)
print(s)
print(len(s))
class Person(object):
def __new__(cls, *args, **kwargs):
print('__new__被调用执行了,cls的id值为{0}'.format(id(cls)))
obj = super().__new__(cls)
print('创建对象的id值为{0}'.format(id(obj)))
return obj
def __init__(self, name, age):
print('__init__被调用了,self的id值为{0}'.format(id(self)))
self.name = name
self.age = age
print('object这个类对象的id为{0}'.format(id(object)))
print('Person这个类对象的id为{0}'.format(id(Person)))
# 创建Person类的实例对象
p1 = Person('张三', 20)
print('p1这个Person类的实例对象的id:{0}'.format(id(p1)))
'''输出:
object这个类对象的id为140707984993104
Person这个类对象的id为1427494206928
__new__被调用执行了,cls的id值为1427494206928
创建对象的id值为1427495955328
__init__被调用了,self的id值为1427495955328
p1这个Person类的实例对象的id:1427495955328
'''
类的浅拷贝与深拷贝
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk
# (1)变量的赋值
cpu1 = CPU()
cpu2 = cpu1
print(cpu1, id(cpu1))
print(cpu2, id(cpu2))
# (2)类的浅拷贝
print('------------')
disk = Disk() # 创建一个Disk类对象
computer = Computer(cpu1, disk) # 创建一个Computer类对象
# 浅拷贝
import copy
print(disk)
computer2 = copy.copy(computer)
print(computer, computer.cpu, computer.disk)
print(computer2, computer2.cpu, computer2.disk)
#深拷贝
print('------------')
computer3=copy.deepcopy(computer)
print(computer, computer.cpu, computer.disk)
print(computer3, computer3.cpu, computer3.disk)
'''输出:
<__main__.CPU object at 0x0000020638BF65E0> 2225745126880
<__main__.CPU object at 0x0000020638BF65E0> 2225745126880
------------
<__main__.Disk object at 0x0000020638BC86D0>
<__main__.Computer object at 0x0000020638C0D430> <__main__.CPU object at 0x0000020638BF65E0> <__main__.Disk object at 0x0000020638BC86D0>
<__main__.Computer object at 0x0000020638C0DC70> <__main__.CPU object at 0x0000020638BF65E0> <__main__.Disk object at 0x0000020638BC86D0>
------------
<__main__.Computer object at 0x000001F78328D430> <__main__.CPU object at 0x000001F7832765E0> <__main__.Disk object at 0x000001F7832486D0>
<__main__.Computer object at 0x000001F784ED7310> <__main__.CPU object at 0x000001F784ED7370> <__main__.Disk object at 0x000001F784ED76A0>
'''
十四章 模块
什么叫模块、模块化编程的好处
模块的导入
导入自定义的模块需要 右键当前目录,选择Mark Directory as,再选择Sources Root
以主程序方式运行
if __name__=='__main__': # 只有运行当前程序时,才会执行pass代码
pass
python中的包
使用import方式进行导入时,只能跟包名或模块名
使用from …import可以导入包,模块,函数,变量
python中常用的内置模块
第三方模块的安装与使用
十五章 文件操作
编码格式
文件读写原理
常用的文件打开模式
文件对象的常用方法
With语句
with open(' logo.png','rb') as src_file:
with open('copy2logo.png','wb') as target_file:
target_file.write(src_file.read ())
以上代码实现文件的复制
文件操作推荐使用with语句,这样不用手动去写关闭操作
目录操作
#OS 模块是与操作系统相关的一个模块
import os
os.system('notepad.exe') #打开记事本
os.system('calc.exe') #打开计算器
# 接调用可执行文件
os.startfile('C:\\Program Files\\Tencent\\QQ\\Bin\\qq.exe')
实操案例——学生信息管理系统
import os
filename = 'student.txt'
def main():
while True:
menu()
choice = int(input('请选择'))
if choice in range(0, 8):
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 menu():
print("====================学生信息管理系统====================\n")
print('--------------------功能菜单---------------------------')
print('\t\t\t\t\t1.录入学生信息')
print('\t\t\t\t\t2.查找学生信息')
print('\t\t\t\t\t3.删除学生信息')
print('\t\t\t\t\t4.修改学生信息')
print('\t\t\t\t\t5.排序')
print('\t\t\t\t\t6.统计学生总人数')
print('\t\t\t\t\t7.显示所有学生信息')
print('\t\t\t\t\t0.退出')
print('-----------------------------------------------------')
def insert(): # 录入学生信息
student_list = []
while True:
id = input('请输入ID(如1001):')
if not id:
break
name = input('请输入姓名:')
if not name:
break
try:
english = int(input('请输入英语成绩:'))
python = int(input('请输入Python成绩:'))
java = int(input('请输入java成绩:'))
except:
print('输入无效,不是整数类型,请重新输入')
continue
# 将录入的学生信息保存到字典中
student = {'id': id, 'name': name, 'english': english, 'python': python, 'java': java}
# 将学生信息添加到列表中
student_list.append(student)
answer = input('是否继续添加? y/n')
if answer == 'y':
print()
continue
else:
print()
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:
id = ''
name = ''
if os.path.exists(filename):
mode = input('按ID查找请输入1,按姓名查找请输入2:')
if mode == '1':
id = input('请输入学生ID:')
elif mode == '2':
name = input('请输入学生姓名:')
else:
print('您的输入有误,请重新输入!')
search()
with open(filename, 'r', encoding='utf-8') as rfile:
student = rfile.readlines()
for item in student:
d = dict(eval(item))
if id != '': # 按ID查
if d['id'] == id:
student_query.append(d)
elif name != '': # 按姓名查
if d['name'] == name:
student_query.append(d)
# 显示查询结果
show_student(student_query)
# 清空列表
student_query.clear()
answer = input('是否继续查询? y/n')
if answer == 'y' or answer == 'Y':
continue
else:
break
else:
print('暂未保存学生信息')
return
def show_student(lst):
if len(lst) == 0:
print('没有查找到学生信息,无数据显示!!!')
return
# 定义标题显示格式
format_title = "{:^6}\t{:^12}\t{:^8}\t{:^10}\t{:^10}\t{:^8}"
print(format_title.format('ID', '姓名', '英语成绩', 'Python成绩', 'Java成绩', '总成绩'))
# 定义内容显示格式
format_data = "{:^6}\t{:^12}\t{:^8}\t{:^8}\t{:^8}\t{:^8}"
for item in lst:
print(format_data.format(item.get('id'),
item.get('name'),
item.get('english'),
item.get('python'),
item.get('java'),
int(item.get('english')) + int(item.get('python')) + int(item.get('java'))
))
def delete(): # 删除学生信息
while True:
student_id = 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'id为{student_id}的学生信息已被删除')
else:
print(f'没有找到ID为{student_id}的学生信息')
else:
print('无学生信息')
break
show() # 删除之后重新显示所有学生信息
answer = input('是否继续删除? y/n')
if answer == 'y' or 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
student_id = input('请输入要修改的学生的ID:')
with open(filename, 'w', encoding='utf-8') as wfile:
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成绩:')
except:
print('您的输入有误,请重新输入!!!')
else:
break
wfile.write(str(d) + '\n') # 将修改后的信息写入文件
print('修改成功!!!')
else:
wfile.write(str(d) + '\n') # 将未修改的信息也写入原文件
answer = input('是否继续修改其他学生信息? y/n')
if answer == 'y' or 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)
else:
return
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()
show_student(student_new)
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('暂未保存学生的信息!')
def show(): # 显示所有学生信息
student_list = []
if os.path.exists(filename):
with open(filename, 'r', encoding='utf-8') as rfile:
students = rfile.readlines()
for item in students:
student_list.append(eval(item))
if student_list:
show_student(student_list)
else:
print('暂未保存数据信息!!!')
if __name__ == '__main__':
main()