面对对象进阶
1.多继承中的self
class A:
def bar(self):
print('BAR')
self.f1()
'''
self本身代表的D类的对象d1
d1如果要在他的父类中去寻找f1
首先应该去C类
'''
class B(A):
def f1(self):
print('B')
class C:
def f1(self):
print('C')
class D(C, B):
pass
d1 = D()
d1.bar()
流程分析:
- d1 = D(),最终找到了object里面的__init__方法创建了对象d1
- d1.bar(),执行bar方法,先去C里找,再去B里面找,最后在A中找到了
- 执行A中的bar方法,遇到self.f1(),此时self依然表示对象d1
- 依然先去C里面找方法f1,最终在C中找到了
2.构造方法
2.1 普通构造方法
class Animal:
def __init__(self):
print('A构造方法')
self.ty = '动物'
class Cat(Animal):
def __init__(self):
print('B构造方法')
self.n = '猫'
a = Animal()
c = Cat()
print(a.__dict__)
print(c.__dict__)
'''
A构造方法
B构造方法
{'ty': '动物'}
{'n': '猫'}
'''
2.2 如果我们想将父类的字段ty封装子类Cat创建的对象中去呢?
class Animal:
def __init__(self):
print('A构造方法')
self.ty = '动物'
class Cat(Animal):
def __init__(self):
print('B构造方法')
self.n = '猫'
self.ty = '动物'
# 执行父类的构造方法
a = Animal()
c = Cat()
print(a.__dict__)
print(c.__dict__)
'''
A构造方法
B构造方法
{'ty': '动物'}
{'n': '猫', 'ty': '动物'}
'''
2.3 如果父类的字段较多,创建子类的时候想继承这些字段,需要重复的代码量很大
我们可以执行父类的构造方法super
class Animal:
def __init__(self):
print('A构造方法')
self.ty = '动物'
self.chi = '吃'
self.he = '喝'
self.la = '拉'
# 方法1
class Cat(Animal):
def __init__(self):
print('B构造方法')
self.n = '猫'
super(Cat, self).__init__() # 找到Cat的父类,执行其父类的构造方法
'''
方法2
class Cat(Animal):
def __init__(self):
print('B构造方法')
self.n = '猫'
Animal.__init__(self)
'''
a = Animal()
c = Cat()
print(a.__dict__)
print(c.__dict__)
'''
A构造方法
B构造方法
A构造方法
{'ty': '动物', 'chi': '吃', 'he': '喝', 'la': '拉'}
{'n': '猫', 'ty': '动物', 'chi': '吃', 'he': '喝', 'la': '拉'}
'''
3.面对对象中的反射
3.1基本用法
class Foo:
def __init__(self, name):
# 类的字段
self.name = name
def show(self):
print('show')
obj = Foo('alex')
# 通过类,找到类的方法
r1 = hasattr(Foo, 'show')
print(r1)
'''
True
'''
# 通过对象,既可以找到对象的成员,也可以找到类里的成员
r2 = hasattr(obj, 'name') # 找到对象的成员
r3 = hasattr(obj, 'show') # 通过类对象指针,可以找到类的方法
print(r2, r3)
'''
True True
'''
3.2 通过字符导入模块,用反射操作类的成员
class Foo: def __init__(self, name): # 类的字段 self.name = name def show(self): print('show')