多态性(主要是来定标准的,而不是继承父类的功能,应用于多继承)
鸭子类型:强耦合思想,把不是同一种事物的用法统一在一起(归一的思想),使用者使用起来会更加方便
多态:同一种事物有多种形态
代码演示
import abc
class Animal(metaclass=abc.ABCMeta): # 导入adc模块强行统一标准,如果子类的代码不写成talk的函数名调用会直接报错
@abc.abstractmethod
def talk(self):
pass
注意:导入adc模块后的父类只能作为一个标准去定标准,不能再实例化去使用
class Animal:
def talk(self):
pass
class Dog(Animal):
def talk(self):
print("汪汪汪")
class Cat(Animal):
def talk(self):
print("喵喵喵")
class Pig(Animal):
def talk(self):
print("哼哼哼")
obj1 = Dog()
obj2 = Cat()
obj3 = Pig()
obj1.talk()
obj2.talk()
obj3.talk()
def talk(animal):
animal.talk()
talk(obj1)
talk(obj2)
talk(obj3)
len多态原理演示
"aaa".__len__()
[].__len__()
{
}.__len__()
def len(obj):
return obj.__len__()
内置方法
class Foo:
pass
obj = Foo() # obj是Foo的一个对象,也可以讲Foo是obj的一个实例
print(isinstance(obj, Foo)) # isinstance 用来判断obj是不是Foo的一个实例
print(isinstance([1, 2, 3], list))# isinstance 用来判断[1,2,3]是不是Foo的一个实例
print(issubclass(Foo, object)) # 判断Foo是否是object的子类
__开头并且__结尾的属性会在满足某种条件下自动触发
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self): # str用来控制对象显示打印结果的,str没有参数,返回值必须是str类型
return "%s %s" % (self.name, self.age)
obj = People("nana", 18)
print(obj) # print(obj._str_())
class People:
def __init__(self, name, age):
self.name = name
self.age = age
self.f = open("a.txt", mode="rt", encoding="utf-8")
def __del__(self): # 类的对象被删除后,会自动触发del的运行
self.f.close()
obj = People("nana", 18)
del obj
print("=========end============")
反射(类与对象里面全都通用)
hasattr:判断对象是否拥有某个属性
getattr: 获得对象中的某个属性 (查)
setattr:将对象中某个属性设置为新的属性 (增,改。属性没有就增加,有就覆盖)
delattr:删除对象中的某个属性 (删)
class People:
country = "China"
def __init__(self, name, age):
self.name = name
self.age = age
def tell_info(self):
print(self.name, self.age)
obj = People("nana", 18)
print(hasattr(obj, "country")) # hasattr判断能不能调用到obj.country,会先从对象里面去查看,找不到会从类里面去找
res = getattr(obj, "country") # getattr取值obj.country
print(res)
res = getattr(obj, "tell_info") # getattr可以拿到obj与tell_info的绑定方法
print(res)
method = getattr(obj, "tell_info")
method()
setattr(obj, "xxx", 111) # obj.xxx=111
print(obj.xxx)
delattr(obj, "name") # 删除obj里面self.name
print(obj.name)
异常处理
什么是异常
异常是错误发生的信号,
程序一旦出错就会产生一个异常
如果该异常没有被处理,该异常就会抛出来,程序的运行也随即终止
错误一般分为两种
1.语法错误
2.逻辑错误
如何处理异常
语法错误->程序运行前就必须改正确
逻辑错误->针对可以控制的逻辑错误,应该直接在代码层面解决
针对不可以控制的逻辑错误,应该采用 try…except…
可控的逻辑错误案例:
age = input("age:").strip()
if age.isdigit():
age = int(age)
if age > 19:
print("too big")
elif age < 19:
print("too small")
else:
print("you got it")
else:
print("输入的必须是数字")
try…except… 是一种异常产生之后的补救措施
# try...except...的完整语法
print("start...")
try:
被监测的代码块1
被监测的代码块2
被监测的代码块3
被监测的代码块4
被监测的代码块5
except 异常的类型1 as e:
处理异常的代码
except 异常的类型2 as e:
处理异常的代码
except 异常的类型3 as e:
处理异常的代码
except (异常的类型4,异常的类型5,异常的类型6)as e:
处理异常的代码
except Exception: # Exception可以处理所有的异常,保证程序的正常运行
处理异常的代码
else:
没有发生异常时要执行的代码
finally:
无论异常与否,都会执行该代码,通常用来进行回收资源的操作
print("end...")
# 注意try可以只跟except,finally联用,但是try不能else联用
try…except…模拟不可控逻辑案例演示
案例1:
print("start...")
try:
print(111)
print(222)
l = [11, 22, 33]
l[100]
print(333)
except IndexError as e: # 异常处理对上了就显示异常提示信息,抛出异常后继续执行代码
print(e)
print("end...")
案例2:
print("start...")
try:
print(111)
print(222)
l = [11, 22, 33]
l[100]
print(333)
except KeyError as e: # 异常对不上会直接报错,不会继续执行代码,程序直接崩掉
print(e)
print("end...")
案例3:
print("start...")
try:
print(111)
print(222)
l = [11, 22, 33]
l[0]
dic = {
"k1": 111}
dic["kkk"]
print(333)
except Exception as e: # except Exception可以抛出异常,后继续执行代码
print(e)
else: # 没有发生异常时要执行的代码
print("else的代码")
finally: # 无论异常与否,都会执行该代码,通常用来进行回收资源的操作
print("=====>finally的代码")
print("end...")
断言 raise 自定义异常
断言代码呈现
l = [111, 222]
# if len(l) != 3:
# raise Exception("必须达到三个值")
assert len(l) == 3 # 判断条件是否成立,如果条件不成立抛出异常,不会再执行后续代码,一般适用于测试代码的时候,如果条件成立,assert就会当作不存在
print("后续代码")
raise
raise IndexError("索引错误") # 主动抛异常,自己指定规则的时候可以用raise制定异常
自定义异常
class Permissio(BaseException):
def __init__(self, msg):
self.msg = msg
raise Permissio("权限错误") # 自己制定异常