深入类与对象
鸭子类型
鸭子类型:用来判断对象的类型,不关注对象的类型,而关注对象具有的行为(方法)一只鸟走起来像鸭子,游起泳也像鸭子,那么它就可以被当做鸭子。
class Dog:
def info(self):
print('i am a dog')
class Cat:
def info(self):
print('i am a cat')
class Duck:
def info(self):
print('i am a duck')
list_a=[Dog,Cat,Duck]
for i in list_a:
i().info()
鸭子类型 在运行之前 Cat,Dog都是在列表里面,当作变量
当运行时,加上()调用info() 才明确Cat是一个类
抽象基类
抽象基类:abc模块,abstract base class,定义各种方法而不被具体实现的类
- 检测类中是否存在某种方法
- 强制重写(两种方式,方式一:主动抛出异常,子类如果不重写父类方法访问时,直接抛出异常,调用时检测;方式二:用装饰器 @abc.abstractmethod强制把方法变成抽象基类的方法,实例化的时候检测用抽象基类的好处是可以把对象中共同的代码放在一起,相当于扫码付钱时的付款二维码,基本付钱都要用二维码。把它做成一个东西)
type和isinstance的区别
- isinstance,布尔值,考虑继承关系
- type 对象的类型不考虑继承
实例属性和类属性的查找
当对象自己有该实例属性的时候,就直接输出自己的;当对象自己没有该属性的时候,才会向类向上查找。
python自省机制
- dict 字典,当前对象的属性
- dir()列表,考虑继承的成员(相当于族谱)
- hasattr(),可以访问到对象里是否含有某种方法
super()
作用:重写或调用父类的方法,是软编码的形式,用父类的类名去调用就是硬编码。
#列子
class A(object):
def __init__(self):
print("A")
class B(A):
def __init__(self):
print("B")
# 重写父类的构造方法 再调用父类的方法
super().__init__()
b = B()
软编码和硬编码
class Person(object):
def __init__(self, name, age, weight):
self.name = name
self.age = age
self.weight = weight
def speak(self):
print(f"{self.name}说:我{self.age}岁")
class Student(Person):
def __init__(self, name, age, weight, grade):
# 软编码 -> 父类的名字可以随便更改
# super().__init__(name, age, weight)
# 硬编码 很生硬
Person.__init__(self, name, age, weight)
self.grade = grade
def speak(self):
print(f"{self.name}说:我{self.age}岁,我在{self.grade}年级")
hz = Student('hz', 20, 120, 2)
hz.speak()