我是基于 deepseek v3 的 AI 助手

本文深入探讨了Python中的面向对象编程(OOP)和异常处理机制。首先,文章介绍了类方法和静态方法的使用,展示了如何通过`@classmethod`和`@staticmethod`装饰器来定义这些方法,并通过实例代码演示了它们的应用场景。接着,文章详细解释了魔法方法(如`__init__`和`__str__`)的作用,帮助读者理解如何在类中自定义对象的行为。 在继承部分,文章通过一个简单的例子展示了如何创建子类并重写父类的方法,同时介绍了`super()`函数的使用,帮助读者理解如何在子类中调用父类的构造函数。 异常处理部分则重点讲解了如何抛出和捕获异常。文章通过代码示例展示了`raise`和`assert`关键字的使用,以及如何通过`try...except...else...finally`结构来处理不同类型的异常。此外,文章还介绍了如何自定义异常类,并提供了练习题,帮助读者巩固所学知识。 最后,文章通过一个练习题,引导读者使用`while`循环和异常处理机制来模拟`for`循环的功能,进一步加深对迭代器和生成器的理解。 这篇文章不仅适合Python初学者,也适合有一定经验的开发者,帮助他们更好地掌握面向对象编程和异常处理的技巧。

# 面向对象

# 类方法和静态方法

# 类方法

class Dog:
    variety = "柴犬"
    def __init__(self, name):
        self.name = name
    @classmethod
    def show_variety(cls):
        print(f"这个类下所有对象都是{cls.variety}")
    def __str__(self):
        return f"{self.name}是一只狗"
dog = Dog("dog")
dog.show_variety()
print(dog)

variety 是类变量,通过这个类实例化的所有对象都有这个变量
在方法前加上 @classmethod 来声明这是一个类方法
类方法的首位参数应为 cls , 代表调用的对象的类 / 类

首位参数可以是任何合法的形参名,但一般使用 selfcls

# 静态方法

class Dog:
    def __init__(self, name):
        self.name = name
    @staticmethod
    def demo():
        print("这是一个静态方法")
    def __str__(self):
        return f"{self.name}是一只狗"
dog = Dog("dog")
dog.demo()
print(dog)

静态方法没有特殊参数,所以和类外函数基本一致

静态方法可以传入参数

# 魔法方法

魔法方法指 class 内的部分特殊方法,通常以双下划线开头结尾
例如 __init__ 就是初始化类时执行的方法
__str__ 就是输出时执行的方法
可以看官方文档

# 继承

class Dog:
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return f"{self.name}是一只狗"
class Huskies(Dog):
    def __init__(self, name):
        super().__init__(name)
        self.variety = "哈士奇"
    def eat(self):
        print(f"{self.name}正在吃")
    def sleep(self):
        print(f"{self.name}正在睡")
    def __str__(self):
        print(f"{self.name}是一只哈士奇")

在这个例子中, HuskiesDog 的派生类 (子类), DogHuskies 的父类 (基类)
Huskies 类重写了实例化和输出方法,Huskies 类拥有所有 Dog 类的方法和变量
子类语法:

class name(父类):
    语句

有时候会有这样的语法:

class Demo(object):
    pass

object 是所有 python 类的基类,在 python2 时必须要写入,但 python3 不需要这样写

# 超类

def __init__(self, name):
    super().__init__(name)
    self.variety = "哈士奇"

这是 Huskies 类的实例化方法,里面的 super() 就是超类
super() 在 Huskies 类内代表 Dog 类,也可以使用 Dog.__init__() 来代替超类

# 异常处理

# 抛出异常

u = input("输入1或0:")
if u:
    raise ValueError("一个错误")

输入 1 就会抛出 ValueError 错误,因为使用了 raise 关键字
语法: raise 错误
但这个代码还可以简化:

u = input("输入1或0:")
assert not u

assert 关键字在后面的变量为非时会返回 AssertionError
assert 不可以选择返回错误

# 异常捕获

# 捕获语法

try:
    u1 = int(input())
    u2 = int(input())
    a = u1/u2
except ZeroDivisionError:
    print("触发了除零错误")
except ValueError:
    print("触发了数值错误")
except Exception as e:
    print(f"触发了{e}")
else:
    print("没有错误")
    print(a)
finally:
    print("有没有错我都输出")

try 关键字后的代码块会被尝试执行,如果触发错误便会寻找 except 子句
execpt 语法: except 异常:
如果没有触发错误,就会寻找 else 子句,没有 else 子句就会继续执行
如果有 finally 子句,就会执行,无论是否触发错误
execpt Exception as e 就是在处理未知错误,这里的 e 就是错误的临时变量

如果在 try 代码块内触发异常,将会直接跳出代码块,处理后下面需要使用 try 内定义的变量
可能导致未定义错误

# 捕获的特殊情况

try:
    5/0
except ZeroDivisionError:
    raise Exception
else:
    raise Exception
finally:
    raise Exception

这是一段离谱的代码,如果执行,就会出现这样一串字:
During handling of the above exception, another exception occurred:
这行字代表在处理 try 内错误时,except 或 finally 内有 raise 子句或抛出了其他错误

except 子句内有 raise 且被触发会导致错误无法正常处理,上面的代码也会抛出 ZeroDivisionError: division by zero

# 定义异常

class MyException(Exception):
    pass

这是一个最简单的异常类,但我们可以给它加上一个实例化函数:

class MyException(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return self.value

现在就可以自定义异常输出了

# 练习题

whlietry...except... 子句来实现 for 循环遍历迭代和生成器的功能
输出 next 返回值即可

超出迭代器序列是 StopIteration 错误

这是数据:

list1 = [1,2,3,4,5]
l = iter(list1)

答案:

while True:
    try:
        temp = l.__next__()
    except StopIteration:
        break
    else:
        print(temp)

下一篇是 9plus, 关于第三方库