day19异常捕获和继承多态

本文详细讲解了Python中的异常处理机制,包括try-except-finally结构,以及如何利用多态实现不同角色员工工资的灵活计算。通过实例演示了处理 FileNotFoundError 和 IOError 的场景,以及如何通过继承和重写抽象类实现多态。
摘要由CSDN通过智能技术生成
day19
1.python中的异常处理机制
"""
代码本身即便没有问题,但在运行的时候可能因为外部环境或资源的问题,导致代码无法运行,程序出现异常状况,如果异常状况没有处理,那么程序就会崩溃,具体表现就是代码停止运行。如果不希望程序崩溃,就要对代码进行异常状况的处理,在python中,可以使用try语法将可能出现状况的代码保护起来,在出现状况的时候,使用except进行异常状况的捕获,并给出相应的处理

注意:如果程序没有发生状况,except都不会执行

可以通过将except FileNotFoundError as err:将异常别名为err,通过err对象就可以获取关于异常的各种信息
"""
# 没有readme.txt这个文件时
import time
import sys
while True:
    # 用try把可能出现状况的代码保护起来执行
    try:
        with open('readme.txt') as file:
            print(file.read())     # FileNotFoundError: [Errno 2] No such file or directory: 'readme.txt'
        break    # 如果文件存在正常执行后就跳出循环
	except FileNotFoundError: # 对号入座,如果文件找不到,此处就会进行异常捕获
    	print('文件不存在,5秒钟之后重新尝试读取该文件')
        time.sleep(5)
	except IOError:  # # 对号入座,如果读文件发生了问题,此处会进行异常捕获
        print('错误提示:读取文件失败,请确认设备是否就绪')
        sys.exit(1)   # 关掉python解释器
    # 在实际项目开发中,这里要通过日志记录问题,可能还会通过网络异常反馈给开发者(需要网络支持)
    except Exception:  # 如果前面两个都没能对号入座,出现其他问题时就用Exception进行异常捕获
        print('错误提示:程序发生了一点小问题,请拨打1110-123寻求帮助')
        sys.exit(1)   # 程序直接退出
    finally:       # 实际项目中,此处通常用来释放外部资源(例如网络连接,数据库连接等),因为这里的代码在任何情况下一定会被执行到,我们把这里称为总是执行代码,但在这里不会,因为在while True循环中不会结束
        print('这个地方最适合释放外部资源')
        print('程序结束!!!')
# 异常关键字:try, except, finally, raise
# raise关键字,抛出一个异常,引出一个异常
2.多态
"""
override - 重写/覆盖/置换 -> 子类将父类已有的方法重新实现一遍
子类继承父类的方法后,子类还可以重写父类的方法(重新实现该方法),不同的子类可以对父类的同一个方法给出不同的实现版本,这样方法在程序运行时就会表现出多态行为(调用相同的方法,做了不同的事情)
多态 - 不同的对象接收到相同的消息做了不同的事情
"""
"""
例子:给员工结算工资的系统:
公司有三类员工,结算工资的方式是不一样的
部门经理:15000元/月
程序员:计算工时 200元/时 * 本月工时
销售员:底薪 + 提成 1800元 + 本月销售额的5%的提成
给出员工的信息,自动结算员工月薪
员工:employee, 雇主:employer 薪水:salary 部门经理:manager 程序员:programmer 销售员:salesman
"""
# 抽象类,让Employee不能创建对象,抽象类:类名(mateclass=ABCMeta)
from abc import ABCMeta, abctractmethod        # abc- 抽象
class Employee():
    def __init(self, name):
        self.name = name
    
    @abctractmethod      # 告诉子类重写实现该方法
    def get_salary(self):
        pass  # 因为员工的薪资计算方式不同所以需要在子类中重写该方法
    
class Manger(Employee):
    def __init__(self, name):
        super().__init__(name)
    def get_salary(self):
        return 15000
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 = [
        Manger('曹操'), 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()}元')
        
 
if __name__ == '__main__':
    main()
# 练习:写一个分数类
"""
属性:分子,分母
方法:加法、减法、乘法、除法
相关单词:
分数 - fraction
分子 - numerator
分母 - denominator
add / substract / multiply / divide
"""
def gcd(x, y):
    while y % x != 0:
        x, y = y % x, x
    return x
# 自定义异常类型通常直接继承Exception类或者它的子类,通过继承Exception自定义异常类型:自定义异常类型通常里面不用写什么代码,主要就是定义一种新的自定义类型来标记特殊的异常状况,代码直接复用Exception的代码
class FractionException(Exception):
    pass

class Fraction:
    
    # 除了用构造器语法,也可以使用类方法类创建对象
    @classmathod
    def from_value(cls, value: float, base=10000):
        """
        将小数转换成分数
        :param value: 要转换的小数
        :param base: 倍数
        :return: 类对象
        """
        return cls(int(value * base), base)
    
    @classmathod
    def from_string(cls, string:str):
        """
        将字符串转换成分数
        :param string: 字符串
        :return: 类对象
        """
        items = string.split('/')
        num, den = [int(item.split()) for item in items]
        return cls(num, den)
    
    def __init__(self, nem, den):
         """
        初始化方法
        :param num:分子
        :param den:分母
        """
        # 如果分母为0,直接引发异常让程序崩溃
        # 通过raise关键字,引发异常,后面跟上异常对象来引发异常,如果使用这个代码的人没有做异常处理,那么程序就会在者个地方崩溃
        if den == 0:
            raise FractionException('分母不能为0')
        self.num = num
        self.den = den
        self.simplay()
        self.normalize()
        
    
    def __str__(self):
        """
        格式化输出
        :return: f'{self.num}/{self.den}'
        """
        if self.den == 1:
            return f'{self.num}'
        return f'{self.num}/{self.den}'
    
    def simplay(self):
        """化简"""
        # abs(数) - 求一个数的绝对值
        factor = gcd(abs(self.num), abs(self.den))   # 调用gcd函数求分子和分母的最大公约数
        self.num, self.den = self.num // factor, self.den // factor
        return self
    
    def normalize(self):
        """规范化"""
        if self.num == 0:
            self.den = 1
        elif self.den < 0:
            self.den = -self.den
            self.num = -self.num
        return self
        
    
    # 魔法方法 里面写自己的加法运算代码,创建对象时直接可以用运算符‘+’进行分数之间的加法运算
    def __add__(self, other):
        num = self.num * other.den + self.den * other.num
        den = self.den * self.num
        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)
    
      # 魔法方法 里面写自己的加法运算代码,创建对象时直接可以用运算符‘x’进行分数之间的加法运算
    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装饰器,转换成属性处理
    @property   # @property会将value方法变为一个属性,调用的时候不用加小括号,直接调用
    # 注意:一般没有参数的方法可以加@property,将其变为属性
    def value(self):
        """将分数变为小数"""
        return self.num / self.den
    
s1 = Fraction(1, 2)
s2 = Fraction(3, 4)
f1 = Fraction(-6, -9)
print(f1)

print(s1 + s2 + f1)
print((s1 + s2) * f1 / s1)

s1 *= s2
print(s1)

f2 = Fraction.from_string('6 / 9')
print(f2)

f3 = Fraction.from_value(0.75)
print('f3', f3)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值