# 面向对象
# 类方法和静态方法
# 类方法
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
, 代表调用的对象的类 / 类
首位参数可以是任何合法的形参名,但一般使用 self
和 cls
# 静态方法
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}是一只哈士奇") |
在这个例子中, Huskies
是 Dog
的派生类 (子类), Dog
是 Huskies
的父类 (基类)
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 |
现在就可以自定义异常输出了
# 练习题
用 whlie
和 try...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, 关于第三方库