# 面向对象

# 类方法和静态方法

# 类方法

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, 关于第三方库