10月14日学习总结
一、Python异常处理机制
代码本身即便没有问题,但在运行时可能因为外部环境或资源的问题,
导致代码无法运行,程序出现异常状况 ,如果异常状况没有得到处理,那么程序就会
崩溃,具体的表现就是代码直接停止运行。如果不希望程序崩溃,就有对代码进行异常
状况的处理,在Python中,可以使用try语法将可能出现状况的代码保护起来执行,在
出现状况的时候,使用except进行异常状况捕获并给出相应的处理
import time
while True:
# 用try把可能常出现异常状况的代码保护起来执行
try:
with open('readme.txt',encoding='utf-8') as file:
print(file.read())
break
# 如果程序运行没有发生状况,except都不会执行
except FileNotFoundError:# 对号入座:如果文件找不到,此处会进行异常捕获 except FileNotFoundError as err:将异常别名为err,通过err对象就可以获取关于异常的各种信息
print('错误提示:文件不存在,5秒后重新尝试读取文件')
time.sleep(5)
except IOError:# 对号入座:如果是读文件发生了问题,此处会进行异常捕获
print('错误提示:读取文件失败,请确认文件是否就绪')
sys.exit(1)
except Exception:# 前面两种都没能对号入座,在此处进行异常捕获,大部分的异常都是Exception的子类型
print('错误提示:程序发生了一点小问题,请拨打110寻求帮助')# 实际项目中,这里要通过日志记录问题,可能还会通过网络将异常信息反馈给开发者(需要网络支持)
sys.exit(1)
finally:# 实际项目中,此处通常用来释放外部资源(例如网络链接,数据库链接等)因为这里的代码在任何情况下一定会被执行到,我们把这里成为总是执行代码
print('这个地方最适合释放外部资源!!!')
print('程序结束')
二. 面对象编程进阶
# def gcd(x,y):
# for i in range(min(x,y),1,-1):
# if x % i == 0 and y % i == 0:
# return i
# return 1
def gcd(x, y):
"""求最大公约数"""
while y % x != 0:
x, y = y % x, x
return x
# 通过继承Exception自定义异常类型
class FractionException(Exception): # 自定义异常类型通常都是继承Exception类或者它的子类
pass # 自定义异常类型通常也不需要写什么代码,主要就是定义一种新的自定义的类型来标记特殊的异常状况,代码直接复用Exception的代码
class Fraction:
"""分数"""
@classmethod
def from_value(cls, value: float):
return cls(int(value * 10000), 10000)
@classmethod
def from_string(cls, string: str):
# num, den = map(int,map(str.strip,string.split('/')))
# num, den = [int(item.strip()) for item in string.split('/')]
return cls(*[int(item.strip()) for item in string.split('/')])
def __init__(self, num, den):
# 如果分母为0,直接引发异常让程序崩溃
if den == 0:
raise FractionException('分母不能为0') # 通过raise关键字,后面跟上异常对象来引发异常,如果使用这个代码的人没有做异常处理,那么程序就会在这个地方崩溃
self.num = num
self.den = den
self.normalize()
self.simplify()
def __str__(self):
if self.den == 1:
return f'{self.num}'
return f'{self.num}/{self.den}'
def __add__(self, other):
num = self.num * other.den + self.den * other.num
den = self.den * other.den
return Fraction(num, den)
def __sub__(self, other):
num = self.num * other.den - self.den * other.num
den = self.den * other.den
return Fraction(num, den)
def __mul__(self, other):
num = self.num * other.num
den = self.den * other.den
return Fraction(num, den)
def __truediv__(self, other):
num = self.num * other.den
den = self.den * other.num
return Fraction(num, den)
@property
def value(self): # 计算属性:通过对象现有的属性运算都得到的一个值,本来是一个方法,但是我们可以通过添加@property装饰器,将它处理成属性
return self.num / self.den
def simplify(self):
"""化简"""
if self.num != 0:
factor = gcd(abs(self.num), abs(self.den))
self.num, self.den = self.num // factor, self.den // factor
return self
def normalize(self):
"""规范化"""
if self.num == 0:
self.den = 1
if self.den < 0:
self.num = -self.num
self.den = -self.den
return self
f1 = Fraction.from_string('5/8')
f2 = Fraction.from_value(0.33)
print(f1)
print(f2)
f3 = f1 + f2
f4 = f1 - f2
f5 = f1 * f2
f6 = f1 / f2
print(f3)
print(f4)
print(f5)
print(f6.value)
三、多态
"""
example06 - 工资结算系统
公司有三类员工,结算工资的方式是不一样的:
- 部门经理:15000元
- 程序员 --->计算工时--->200元/小时
- 销售员 --->底薪+提成 --->1800元 + 销售额5%提成
给出员工的信息,自动结算月薪
override ---> 重写/覆盖/置换 ---> 子类将父类已有的方法重新实现一遍
子类可以重写父类的方法,不同的子类可以对一个方法给出不用的实现版本
多态 - 不同的对象(部门经理、销售员、程序员)接收到相同的消息(get_salary)做了不同的事(每种员工结算月薪的方式不一样)
employee employer salary manager programmer salesman
"""
from abc import ABCMeta, abstractmethod
class Employee(metaclass=ABCMeta):
"""员工"""
def __init__(self, name):
self.name = name
@abstractmethod
def get_salary(self):
pass
class Manager(Employee):
"""部门经理"""
def get_salary(self):
return 15000.0
class Programmer(Employee):
"""程序员"""
def __init__(self, name):
super().__init__(name)
self.working_hour = 0
def get_salary(self):
return 200 * self.working_hour
class Salesman(Employee):
"""销售员"""
def __init__(self, name):
super().__init__(name)
self.sales = 0.0
def get_salary(self):
return 1800 + self.sales * 0.05
def main(): # 要实现多态,最重要的一步就是方法重写,子类重写父类已有的方法,
emps = [
Manager('王博杨'), Programmer('王浩宇'), Programmer('曹操'),
Salesman('貂蝉'), Salesman('代吉'), Programmer('罗昊')
]
for emp in emps:
if type(emp) == Programmer:
emp.working_hour = int(input(f'请输入{emp.name}本月工作时间: '))
elif type(emp) == Salesman:
emp.sales = float(input(f'请输入{emp.name}本月销售额: '))
print(f'{emp.name}本月工资为:{emp.get_salary():.2f}元')
if __name__ == '__main__':
main()