python对象的__class__属性,与修改实例对象的__class__属性使执行被覆盖的父类同名方法

 

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$

 

 

 

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值