class A():
def show(self):
print('base show')
@classmethod
def clsA(cls):
print('execute base clsA() occur!')
class B(A):
def show(self):
print('derived show')
@classmethod
def clsB(cls):
print('execute base clsB() occur!')
print('cls in clsB():', cls)
@classmethod
def clsB2(cls, obj):
super(cls, obj).clsA()
print('parameter cls in clsB2(): ', cls) #<class '__main__.B'>
super(__class__, obj).clsA()
print('__class__ in clsB2():', __class__) #<class '__main__.B'>
obj=B()
obj.show() #将访问派生类B的实例方法show()
print('obj former: ', obj) #打印<__main__.B object at 0x7ffaa5d48be0>
print('obj.__class__:', obj.__class__) #<class '__main__.B'>
'''1、类B的实例对象obj的类型属性<class '__main__.B'>表征其是类B的一个实例,'''
obj.__class__=A
print('obj after: ', obj) #打印<__main__.A object at 0x7ffaa5d48be0>
#,地址一样但类型是基类类型
'''2、改变派生类实例对象obj的类型属性__class__为其父类A,就是把obj当作基类A类的实例
对象,其实就是使原来的派生类B类实例对象obj缩小范围到其基类A类部分,因为原来的派生类
B类实例对象整体的类型属性是class B,但其基类A类部分的类型属性是class A,这操作有点
像C++的"用基类指针指向派生类对象"从而使用该基类指针访问基类的实例方法"
'''
obj.show() #将访问基类A的实例方法show()
print('B.__class__:', B.__class__) #<class 'type'>
print('A.__class__:', A.__class__) #<class 'type'>
'''3、类型对象的类型属性就是<class 'type'>,表征其是一个type类的实例,称为类型对象,
类型对象像实例对象一样可以有自己的类方法与类属性(如值恒为<class 'type'>的__class__)
20210401补充:自定义类默认派生自object元基类,表示是描述实例的类,自定义类是构造实例的类。而type元类是构造类的类,构造出的类也是一个对象,也是派生自object元基类,具有__init__()等方法,更像是一个可调用对象,调用后构造出一个实例。
自定义类作为type元类的实例,其类型才是<type 'type'>,比如type<list>打印<type 'type'>,如果构造mylist=[]然后type(mylist)将打印<type 'list'>。
当然,type(type)也打印<type 'type'>,因为type元类构造其他类,type元类本身也是个类型。
总结:type元类构造其他类,其他类作为type元类的实例,是可调用对象,其他类构造实例。object元基类是所有python类的基类。
4、派生类类型对象要调用基类的类方法,也要得到一个基类的类型对象,但不能用更改派生类
类型对象的类型属性__class__的方式来使之成为基类类型对象,因为作为类型对象,二者的内
容是各自独立的,不像派生类实例中有基类实例的部分,并且二者都是type类实例对象,二者
的类型属性__class__都是<class 'type'>。所以不能通过改变类型对象的类型属性来使之
"变成"一个基类类对象
5、python内置builtins模块提供了super类,并提供了函数super(),可以help(super)查看细节
'''
obj2=B()
B.clsB2(obj2)
#super(B, obj).clsA() #<class '__main__.B'>
'''6、在类外就不能调用super(type, obj)函数了,会报错
TypeError: super(type, obj): obj must be an instance or subtype of type'''
python3.8执行输出:
haypin@ubt:~/Files$ python3.8 m08023.py
derived show
obj former: <__main__.B object at 0x7f70ed323be0>
obj.__class__: <class '__main__.B'>
obj after: <__main__.A object at 0x7f70ed323be0>
base show
B.__class__: <class 'type'>
A.__class__: <class 'type'>
execute base clsA() occur!
parameter cls in clsB2(): <class '__main__.B'>
execute base clsA() occur!
__class__ in clsB2(): <class '__main__.B'>
haypin@ubt:~/Files$