Python第一阶段学习总结

【第19天】Python第一阶段学习总结

2021/10/14

一. Python中的异常处理机制

代码本身即便没有问题,但在运行时可能因为外部环境或资源的问题,导致代码无法运行,程序出现异常状况,如果异常状况没有得到处理,那么程序就会崩溃,具体的表现就是代码直接停止运行。

如果不希望程序崩溃,就要对代码进行异常状况的处理,在Python中,可以使用try语法将可能出现状况的代码保护起来执行,在出现状况的时候,使用except进行异常状况捕获并给出相应的处理。

1. try

  1. 用try语法将可能出现状况的代码保护起来执行

2. except

  1. 在出现状况的时候,使用except进行异常状况捕获并给出相应的处理

3. finally

  1. 实际项目中,此处通常用来释放外部资源(例如网络连接、数据库连接等),因为这里的代码在任何情况下一定会被执行到,这里的代码称为总执行代码
import sys
import time

while True:
    try:
        with open('readme.txt', encoding='utf-8') as file:
            print(file.read())
        break
    except FileNotFoundError:
        print('错误提示:文件不存在,5秒钟以后重新尝试读取文件')
        time.sleep(5)
    except IOError:
        print('错误提示:读取文件失败,请确认设备是否就绪')
        sys.exit(1)
    except Exception:
        print('错误提示:程序发生了一点小问题,请拨打400-800-8855寻求帮助')
        sys.exit(1)
    finally:
        print('这个地方最适合放外部资源!!!')
        print('程序结束')

二. 面对象编程进阶

1. 自定义异常

  1. 通过继承Exception自定义异常类型
  2. 自定义异常类型通常都是继承Exception类或者它的子类
  3. 自定义异常类型通常也不需要写什么代码,主要就是定义一种新的自定义的类型来标记特殊的异常状况,代码直接复用父类Exception的代码
  4. raise:关键字 - 引发;通过raise关键字,后面跟上异常对象引发异常,如果使用这个代码的人没有做异常处理,那么程序就会在这个地方崩溃

2. @property:计算属性

  1. 计算属性:通过对象现有的属性运算得到一个值,本来是一个方法,但是我们可以通过添加@property装饰器,将它处理成属性

def gcd(x, y):
    """求最大公约数"""
    while y % x != 0:
        x, y = y % x, x
    return x


'''
1. 通过继承Exception自定义异常类型
2. 自定义异常类型通常都是继承Exception类或者它的子类
3. 自定义异常类型通常也不需要写什么代码,主要就是定义一种新的自定义的类型来标记特殊的异常状况,代码直接复用父类Exception的代码
'''

class FractionException(Exception):
    pass


class Fraction:

    @classmethod
    def from_value(cls, value: float, base=10000):
        return cls(int(value * base), base)

    # '3 / 4'
    @classmethod
    def from_string(cls, string: str):
        num, den = map(int, map(str.strip, string.split('/')))
        # items = string.split('/')
        # num, den = [int(item.strip()) for item in items]
        # return cls(*[int(item.strip()) for item in string.split('/')])    # 解包语法
        return cls(num, den)

    def __init__(self, numerator, denominator):
        # 如果分母为0,直接引发异常让程序崩溃
        if denominator == 0:
            # raise 关键字 - 引发; 通过raise关键字,后面跟上异常对象引发异常,如果使用这个代码的人没有做异常处理,那么程序就会在这个地方崩溃
            raise FractionException('分母不能为0')
        self.numerator = numerator
        self.denominator = denominator
        self.normalize()
        self.simplify()

    def __repr__(self):
        if self.denominator == 1:
            return f'{self.numerator}'
        return f'{self.numerator}/{self.denominator}'

    def simplify(self):
        """化简"""
        if self.numerator != 0:
            factor = gcd(abs(self.numerator), abs(self.denominator))
            self.numerator, self.denominator = self.numerator // factor, self.denominator // factor
        return self       # 可以继续调用其他方法

    def normalize(self):
        """规范化"""
        if self.numerator == 0:
            self.denominator = 1
        elif self.denominator < 0:
            self.numerator = - self.numerator
            self.denominator = - self.denominator
        return self

    def __add__(self, other):
        """+"""
        a = self.numerator
        b = self.denominator
        c = other.numerator
        d = other.denominator
        num = a * d + c * b
        den = b * d
        return Fraction(num, den)

    def __sub__(self, other):
        """-"""
        a = self.numerator
        b = self.denominator
        c = other.numerator
        d = other.denominator
        num = a * d - c * b
        den = b * d
        return Fraction(num, den)

    def __mul__(self, other):
        """*"""
        num = self.numerator * other.numerator
        den = self.denominator * other.denominator
        return Fraction(num, den)

    def __truediv__(self, other):
        """/"""
        num = self.numerator * other.denominator
        den = self.denominator * other.numerator
        return Fraction(num, den)

    # @property:将方法变成属性,方法没有其他的参数才可以用
    @property
    def value(self):
        """分数转换成小数"""
        # 计算属性:通过对象现有的属性运算得到的一个值,本来是一个方法,但是我们可以通过添加@property装饰器,将它处理成属性
        return self.numerator / self.denominator


# f1 = Fraction(-6, 9)
f1 = Fraction.from_string('6 / 9')
print(f1)
# f2 = Fraction(3, -4)
f2 = Fraction.from_value(-0.75)
print(f2)
print(f1, f2)
print(f1 + f2)
print(f1 - f2)
print(f1 * f2)
f3 = f1 / f2
print(f3)
print(f3.numerator / f3.denominator)
print(f3.value)

3. 多态

  1. 元类:meta class
  2. 抽象类:abstract class
  3. 实现多态,最重要的一步就是方法重写,子类重写父类已有的方法,不同的子类给出了不同的实现版本,所以这个方法在运行时就会表现多态行为(接受消息是一样的,做的事情是不一样的)
    1. override —> 重写 / 覆盖 / 置换 —> 子类将父类已有的方法重写写一遍
    2. 子类可以重写父类的方法,不同的子类可以对同一个方法给出不同的实现版本
    3. 多态:不同的对象(部门经理,销售员,程序员)接收到相同的消息(get_salary)做了不同的事情(每月工资不一样)
from abc import ABCMeta, abstractmethod


class Employee(metaclass=ABCMeta):
    """员工"""

    def __init__(self, name):
        """初始化方法
        :param name: 员工姓名
        """
        self.name = name

    @abstractmethod
    def get_salary(self):
        pass


class Manager(Employee):
    """经理"""

    def __init__(self, name):
        super().__init__(name)

    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.0 + 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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值